题目:
五笔的编码范围是a ~ y的25个字母,从1位到4位的编码,如果我们把五笔的编码按字典序排序,形成一个数组如下:a, aa, aaa, aaaa, aaab, aaac, … …, b, ba, baa, baaa, baab, baac … …, yyyw, yyyx, yyyy。其中a的Index为0,aa的Index为1,aaa的Index为2,以此类推。
1)编写一个函数,输入是任意一个编码,比如baca,输出这个编码对应的Index;
2)编写一个函数,输入是任意一个Index,比如12345,输出这个Index对应的编码。
注意到:如果都是4字符的定长串的话,很简单,就是25进制的一个表示法,但这里是不定长的。
1、观察头几个串:a->0, aa->1, aaa->2,aaaa->3。应该可以看出来,这里的索引就是:字符串长度-1;
2、已知a的索引,求b的索引:因为a到b之间隔了以下四种情况的字符串:a后跟1字符的串有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 + 1;
5、已知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是对内部表达式求和。
举例:求cdef索引号过程
c_index = a_index + ('c'-'a')*(25*25*25+1) = 0 + 2*factor[0]
ca_index = c_index + 1
cd_index = ca_index + ('d'-'a')*(25*25+1) = 2*factor[0]+1 + 3*factor[1]
cda_index = cd_index + 1
cde_index = cda_index+('e'-'a')*(25+1) = 2*factor[0]+1 + 3*factor[1]+1 + 4*factor[2]
cdea_index = cde_index + 1
cdef_index = cdea_index+('f'-'a') = 2*factor[0]+1 + 3*factor[1]+1 + 4*factor[2]+1 + 5*factor[3]
程序参考:
int factor[]={25*25*25+25*25+25+1,25*25+25+1,25+1,1}; int encode(char *str) { int len=strlen(str); int index=len-1; for(int i=0;i<len;++i) { index+=factor[i]*(str[i]-'a'); } return index; }
解码过程就是编码过程的逆过程,有了factor数组,就简单多了。
int factor[]={25*25*25+25*25+25+1,25*25+25+1,25+1,1}; char* decode(int index) { char str[4]; int i=0; while(index>=0) { str[i]='a'+index/factor[i]; index=index%factor[i]; --index; ++i; } str[i]='