前几天朋友跟我说了一道面试题:五笔的编码范围是a到y的25个字母,从1位到4位的编码,

如果将五笔的编码按字典序排序,形成数组如下:a, aa, aaa, aaaa, aaab, aaac, ..., b, ba, baa, baaa, baab...yyyx, yyyy

其中a的索引是0,aa的索引是1,aaa的索引是2,aaaa的索引是3,以此类推:

1)、编写一个函数,输入是任意一个合法的字符串,输出这个字符串对应的索引;

2)、编写一个函数,输入是任意一个合法的索引,输出这个索引对应的字符串。

朋友还给我他当时的代码,我看了代码大概20分钟,还不知道他是怎么入手的;然后我就问他:你怎么想到思路的,他说:很自然啊,排列组合!

再想了一会,才领悟过来:差距啊,这就是差距。

记下思路,作个思路备用库也是好的【以下思路是我事后诸葛亮似的小结,但也算是一个思路吧】

注意到:如果都是4字符的定长串的话,很简单,就是25进制的一个表示法,但这里是不定长的。

1、观察头几个串:a-->0, aa->1, aaa->2,aaaa->3:应该可以看出来,这里的索引就是:字符串长度 - 1

2、已知a的索引,求b的索引:因为a到b之间隔了以下四种情况的字符串:a后跟2字符的串有25个(aa,ab,...ay),a后跟2字符的串有25*25个(aaa, aab, ... ayy),a后面跟3字符的串有25*25*25个(aaaa,aaab,...ayyy),然后才是b,所以b的索引 = a的索引 + 25+25*25+25*25*25 + 1,加1是因为b排在a和中间的字符之后1个

3、已知aa的索引,求ab的索引:同理,ab的索引 = aa索引 + 25 + 25* 25 + 1

4、已知aaa的索引,求aab的索引:同理,aab的索引 = aaa索引 + 25 + 15、已知aaaa的索引,求aaab的索引 = aaaa索引 + 1

至于aaaa,aaa,aa, a的索引由1: 可归纳为 字符串长度 - 1

所以:可用一个权重数组来表示修正后的进制:factor[4] = {1+25+25*25+25*25*25, 1+25+25*25, 1+25, 1}

然后字符串string的索引函数为:index(string) = (string.length - 1) + sum[ factor[i] * (string[i] - 'a') ,  {i, 0, string.length-1 } ]

其中sum是对内部表达式求和。

[cpp] view plaincopy
  1. int encode(const char *str)
  2. {
  3. int len = 0;
  4. int index = 0;
  5. int factor[] = {1+25+25*25+25*25*25, 1+25+25*25, 1+25, 1};
  6. while(*str)
  7. index += factor[len++] * (*str++ - 'a');
  8. return index + (len - 1);
  9. }

二、解码:解码过程就是编码过程的逆过程,有了factor数组,就简单多了

[cpp] view plaincopy
  1. // dst为至少5字符的字符数组
  2. void decode(char *dst, int index)
  3. {
  4. int i = 0;
  5. int factor[] = {1+25+25*25+25*25*25, 1+25+25*25, 1+25, 1};
  6. while(index >= 0)
  7. {
  8. *dst++ = 'a' + index / factor[i];
  9. index %= factor[i++];
  10. --index; // 此处要减1,还原到下一个字符
  11. }
  12. *dst = '\0';
  13. }

三、变形:这个问题在朋友的帮助下理清思路之后,我就在想,五笔编码是越常用的字串长越少,按道理是不应该按字典排序的,应该按字母的长短排序比较好:

a, b, ... x, y, aa, ab, ... yy, aaa, aab, ..., yyy, aaaa, aaab, ..., yyyy;如果这样排序,那么索引就好像简单多了?

起码可以按串长来分索引,比如长度为1的串范围[0, 25-1], 长度为2的串范围[25, 25*25-1],以此类推。

但如果不用分段,还有什么办法呢?

最初,我按照上面的思路分析:a到b的距离为1,aa到ab的距离也为1,好像得不到factor数组。

后来,我观察到上面的数组:a的索引为0,aa的索引为25,a和a的差距是0,到第二位了就变成了1*25;再看ba的索引50,b和a的差距是1,到第二位了就变成2*25

再后来,我联系到了以前的一道题目:判断回文数时用到的数字反转的技巧。

好像有底了,写个代码如下:

// 按长度排序的串索引,忽略错误检查

[cpp] view plaincopy
  1. int encode(const char *str)
  2. {
  3. int index = *str++ - 'a';
  4. while(*str)
  5. index = 25 * (1 + index) + (*str++ - 'a');
  6. return index;
  7. }
  8. /*验证了一下,发现是对的,嗯,不用分长度求值了。
  9. *解码过程也是上述过程的逆过程,不过要反转字符串:
  10. */
  11. // 反转字符串str
  12. void ReverseStr(char *str)
  13. {
  14. int i;
  15. int len = strlen(str);
  16. for(i = 0; i < len / 2; ++i)
  17. {
  18. char c = str[i];
  19. str[i] = str[len - 1 - i];
  20. str[len - 1 - i] = c;
  21. }
  22. }
  23. // dst为至少5字符的字符数组
  24. void decode(char *dst, int index)
  25. {
  26. int j;
  27. char *p = dst;
  28. while(index >= 0)
  29. {
  30. *p++ = 'a' + index % 25;
  31. index = index / 25 - 1;
  32. }
  33. *p = '\0';
  34. ReverseStr(dst);
  35. }
  36. /*四、现实:如果在实际应用中,有这样的需求,还是用长度排序的串比较好,又由于用户一天内使用的汉字基本有**限,用哈希将用户输入的串缓冲起来,效率更高。
  37. *五、初衷:写这篇文章,主要是感觉编程实际上并不是那么容易,尤其是编程思维的把握上,很容易出错。感到有点**不大可控,于是趁现在还记起思路时候,将其记下来,以便于未来时不时查看。另外,如果各位有更好的思路,希望**大家能告知。
  38. ******PS. 前几天,又在某网站上碰到判断回文数的问题,我还是按老办法,开一个大数组,将数字一个个的拆到数组里面去,然后依次判断数组是否对称;看了答案,才枉然大悟;但是这个答案我在一年前,二年前...,六年前,就已经重复的看过了,真的是看过就忘,忘了就又回到最初学习编程时候的思路去了。工作时候,写的代码洋洋洒洒;自我感觉也不差,但是遇到这些问题时候,老是分析不出最优方案。
  39. **/

五笔字典序列编码(腾讯面试)相关推荐

  1. 「软件测试」刚从腾讯面试出来,留下了这些面试笔记

    对于想要面试去银行面试的小伙伴们看过来,小编为大家总结了浦发银行的面试题,其实很多面试题很多公司都差不多.主要看自己如何灵活回答.以下的问题小编之前面试非浦发银行的银行项目也有被问到过,是在一面的时候 ...

  2. [zz from byhh]完整的腾讯面试经过

    前言: 从9月10号开始到现在快两个月了,两个多月中,我经历数次面试和笔试,在经历这些的同 时积累了不少的经验,也学到了不少东西,在此把它记录下来,算是和一起找工作中的同 学一起共勉吧.我是本校的学生 ...

  3. 标 题: 腾讯面试题目(PHP程序员)

    发信人: max19830115 (max), 信区: Programming 标  题: 腾讯面试题目(PHP程序员) 发信站: 水木社区 (Mon Apr 18 16:26:07 2011), 站 ...

  4. ❤️详解腾讯面试❤️

    直接用微信扫描如下二维码,畅通无阻阅读------"万字攻略,详解腾讯面试"  ,好评如潮,一天访问量达之前文章的30倍,对有缘人肯定会有所帮助. 如果你是其他阅读方式导致不能扫码 ...

  5. 腾讯面试:一条SQL语句执行得很慢的原因有哪些?

    戳蓝字"CSDN云计算"关注我们哦! 技术头条:干货.简洁.多维全面.更多云计算精华知识尽在眼前,get要点.solve难题,统统不在话下! 作者:帅地 转自:苦逼的码农 说实话, ...

  6. 云漫圈 | 腾讯面试,我竟然输给了final关键字

    戳蓝字"CSDN云计算"关注我们哦! 作者:乔戈里 来源:程序员乔戈里 腾讯面试现场 ------ final 在 Java 中是一个保留的关键字,可以声明变量.方法.类. 什么是 ...

  7. 二叉树的建立与遍历完整代码_腾讯面试官这样问我二叉树,我刚好都会

    前记 上周我投递出了简历,岗位是后端开发工程师.这周腾讯面试官给我进行了视频面试.面试过程中他问了二叉树的问题. 二叉树相关算法题,在面试中出现的次数非常非常多,所以我面试之前也有所准备.今天结合面试 ...

  8. 程序员美团面试挂了,7天后去腾讯面试,见到面试官:好巧啊!!

    说起来,职场上很多事情,只能用一个"缘分"来解释.近日在职场论坛上看到有员工发帖,他说自己在面试时遇到了一件最悲哀的事情?在上个月去美团面试的时候,由于发挥不太好,面试挂了.当时那 ...

  9. (97)序列检测器状态转移图,面试必问(二十一)(第20天)

    (97)序列检测器状态转移图,面试必问(二十一)(第20天) 1 文章目录 1)文章目录 2)FPGA初级课程介绍 3)FPGA初级课程架构 4)序列检测器状态转移图,面试必问(二十一)(第20天) ...

最新文章

  1. jieba分词中cut和lcut的区别
  2. shanghai road map and the operational time for 12306 system
  3. 用内存流 文件流 资源生成客户端(Delphi开源)
  4. 初学Java,这些框架你要掌握
  5. 您是否应该信任JVM中的默认设置?
  6. IdentityServer4实战 - 谈谈 JWT 的安全策略
  7. 微信终端跨平台组件 mars 开源
  8. OpenERP工作流不同角色看属于自己审批的方法
  9. 全网最详细的openstack安装教程
  10. 到底怎么查询域名的IP?(强大的查询网站)
  11. Java正则匹配字母,数字,特殊字符
  12. PCL学习:基于形态学滤波的地面分割
  13. 基于 Paraview 扩展与实现——(2)
  14. GPU显存占满利用率GPU-util奇低
  15. LAMP环境搭建与配置(一)
  16. ise 时钟约束_ISE 约束文件完整讲解
  17. 主成分分析——PCA降维Python实现及碎石图
  18. BACnet - 物联网智能建筑通信协议 - 补充中
  19. php漏洞是什么意思,PHP程序漏洞产生的原因分析与防范方法说明
  20. 快消品牌企业如何打造长红爆品、如何利用数字化赋能企业管理

热门文章

  1. Docker系列六EPIC领游戏
  2. 大数据分析项目实战--天猫订单综合分析
  3. java list集合包含_Java 中的集合类包括 ArrayList 、 Linke
  4. 安卓手机通过OTG转接头连接U盘(USB口)相关问题解决
  5. 想成为牛逼网页设计师吗?
  6. 监管之外:网店新规制约了什么
  7. 试题 算法训练 唯一的啥子ALGO-973
  8. 愤怒的2011幸福的生活
  9. 全球区块链理事会(GBBC)成立中国分会,开启新篇章
  10. C++运行三维人脸重建 VRN