字典序編碼與解碼的兩道題

如果將五筆的編碼按字典序排序,形成數組如下: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 } ]

  1. int encode(char *str) 
  2.     int a[]={1+25*25*25+25*25+25,1+25*25+25,1+25,1}; 
  3.     int length=strlen(str); 
  4.     int index=0; 
  5.     for(int i=0;i<length;i++) 
  6.     { 
  7.         index+=(str[i]-'a')*a[i]; 
  8.  
  9.     } 
  10.     index+=length-1; 
  11.     return index; 
  12.  
  13. void decode(char *str,int index) 
  14.     int a[]={1+25*25*25+25*25+25,1+25*25+25,1+25,1}; 
  15.     int i=0; 
  16.     while(index>=0) 
  17.     { 
  18.         *str='a'+index/a[i]; 
  19.         index%=a[i]; 
  20.         i++; 
  21.         str++; 
  22.          --index; 
  23.     } 
  24.    *str='\0'

如果字典順序換成a, b, ... x, y, aa, ab, ... yy, aaa, aab, ..., yyy, aaaa, aaab, ..., yyyy

這樣就變簡單了許多,可以類似按照26進制來算。

  1. int encode(char *str) 
  2.     int length=strlen(str); 
  3.     int index=0; 
  4.     for(int i=0;i<length;i++) 
  5.     { 
  6.         if(i==length-1) 
  7.  
  8.         index=index*25+str[i]-'a'
  9.         else 
  10.         { 
  11.            index=index*25+(str[i]-'a'+1); 
  12.         } 
  13.  
  14.  
  15.     } 
  16.      
  17.     return index; 
  18. void reverse(char *str) 
  19.     int length=strlen(str); 
  20.     for(int i=0;i<length/2;i++) 
  21.     { 
  22.         char tmp=str[i]; 
  23.         str[i]=str[length-1-i]; 
  24.         str[length-1-i]=tmp; 
  25.     } 
  26. void decode(char *str,int index) 
  27.     char *p=str; 
  28.     while(index>=0) 
  29.     { 
  30.         *p='a'+index%25; 
  31.         index/=25; 
  32.         p++; 
  33.          --index; 
  34.     } 
  35.    *p='\0'
  36.    reverse(str); 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章