前言ios
今天通知過了筆試,但以爲筆試沒來得及作的題仍是要作一下。c++
題目git
第二道題,字符串的,大意就是,給你個形如a,b,c,ab,bb,cb,ac,bc,cc,aab,bab,cab,abb,bbb,cbb,acb,bcb,ccb......按某種規律排列的無限長的字符串數組,要求:數組
1)給定一個位置,輸出對應的字符串。spa
2)給定一個字符串,找出它在這個數組裏的位置。code
思路blog
仔細觀察會發現其實就是用a,b,c在每個字符串上不斷循環頭插獲得新的字符串,好比a,b,c循環在b,c字符上頭插獲得,ab,bb,cb,ac,bc,cc,而後又在,ab,bb,cb,ac,bc,cc字符串的頭部插入獲得,aab,bab,cab,abb,bbb,cbb,acb,bcb,ccb......ccc。也就是說N位長度的一系列字符串是在N-1位長度的字符串上頭插a,b,c獲得的。那麼能夠用一個動態增加的數組來模擬這種狀況,c++的vector是個不錯的選擇。ci
另外還要知道的是:N位長的字符串集合的最後一個字符串在該數組中的位置是3 ^ N,好比1位長的最後一個字符是「c」,位置在3^1 = 3。同理2位長度的最後一個字符串"cc"位置爲9,同理"ccc"位置爲27,以此類推。因此數組無論如何更新,它的長度必定是3^N,且N位長度的字符串的個數爲2 * 3^(N - 2)。字符串
那麼對於 題目1) 求指定位置的字符串有以下代碼:string
#include<iostream> #include<vector> #include<math.h> using namespace std; const string base = "abc"; int main() { int pos; vector<string> res = {"woshishabi","a","b","c"}; //動態增加的字符串數組,從1開始操做更方便 while(cin >> pos) //根據輸入的位置來更新數組 { int index = pos + 1; //加一,由於題目要求從0開始,可是從1開始便於操做。 int len = res.size() - 1; if(index <= len) //先判斷指定位置的字符串所在的字符串集合是否已經在數組中了。 { cout << res[index] << endl; continue; } //沒有的話就把它所在的對應位數的全部字符串放入數組中 int digit = 1; while(pow(3,digit) < index) { digit++; //循環結束獲得須要更新的digit位長的字符串 } int End = pow(3,digit - 1); //digit - 1位字符串的結束位置 //int dis = num - len; int start = 1 + len - 2 * pow(3,res[len].size() - 1); //res中的最多位數的字符串集合的開始位置 while(start != End) //開始更新字符串數組 { for(int i = 0;i < base.size();i++) { string temp = res[start]; temp.insert(0,1,base[i]); res.push_back(temp); } start++; } cout << res[index] << endl; //輸出對應位置的字符串便可 } }
能夠看到初始我是先把a,b,c放入數組中。而後基於輸入的位置來肯定須要更新到的最大位數。
對於題目2)求指定字符串的位置,
1.能夠根據它的長度L肯定它所在集合的最後一個字符串的位置lastpos = pow(3,L)。
2.求這個字符串集合的首位置startpos = lastpos - 2 * 3^(L- 2) + 1。
3.而後在[startpos,lastpos]區間找這個字符串就行,若是lastpos > res的長度,轉4.
4.若是lastpos > res的長度就用題目1)的解決方法更新res的內容就行,而後再去查找。