如果將五筆的編碼按字典序排序,形成數組如下:a, aa, aaa, aaaa, aaab, aaac, ..., b, ba, baa, baaa, baab...yyyx, yyyy
其中a的索引是0,aa的索引是1,aaa的索引是2,aaaa的索引是3,以此類推:
1)、編寫一個函數,輸入是任意一個合法的字符串,輸出這個字符串對應的索引;
2)、編寫一個函數,輸入是任意一個合法的索引,輸出這個索引對應的字符串。
這道題最開始理解字典序列理解錯了,字典序列中aaay後是aab,aayy後是ab,ayyy之後是b
可以想象一個樹結構,第一層每個節點爲1個字母,第二層每個節點爲2個字母,以此類推。
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 + 1
5、已知aaaa的索引,求aaab的索引 = aaaa索引 + 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 } ]
- int encode(char *str)
- {
- int a[]={1+25*25*25+25*25+25,1+25*25+25,1+25,1};
- int length=strlen(str);
- int index=0;
- for(int i=0;i<length;i++)
- {
- index+=(str[i]-'a')*a[i];
- }
- index+=length-1;
- return index;
- }
- void decode(char *str,int index)
- {
- int a[]={1+25*25*25+25*25+25,1+25*25+25,1+25,1};
- int i=0;
- while(index>=0)
- {
- *str='a'+index/a[i];
- index%=a[i];
- i++;
- str++;
- --index;
- }
- *str='\0';
- }
如果字典順序換成a, b, ... x, y, aa, ab, ... yy, aaa, aab, ..., yyy, aaaa, aaab, ..., yyyy
這樣就變簡單了許多,可以類似按照26進制來算。
- int encode(char *str)
- {
- int length=strlen(str);
- int index=0;
- for(int i=0;i<length;i++)
- {
- if(i==length-1)
- index=index*25+str[i]-'a';
- else
- {
- index=index*25+(str[i]-'a'+1);
- }
- }
- return index;
- }
- void reverse(char *str)
- {
- int length=strlen(str);
- for(int i=0;i<length/2;i++)
- {
- char tmp=str[i];
- str[i]=str[length-1-i];
- str[length-1-i]=tmp;
- }
- }
- void decode(char *str,int index)
- {
- char *p=str;
- while(index>=0)
- {
- *p='a'+index%25;
- index/=25;
- p++;
- --index;
- }
- *p='\0';
- reverse(str);
- }