刷題 編寫一個函式,給出可以轉換的不同字串的個數。
阿新 • • 發佈:2018-12-10
題目:
將給定的數轉換為字串,原則如下:1對應 a,2對應b,…..26對應z,例如12258可以轉換為"abbeh", "aveh", "abyh", "lbeh" and "lyh",個數為5,編寫一個函式,給出可以轉換的不同字串的個數。
這是第二課第三題
兩種解法:暴力遞迴和動態規劃
#include<iostream> #include<string> #include<vector> using namespace std; //產生一個10000-100000的隨機數 int CreatRandomNum(){ /* 要取得[a,b)的隨機整數,使用(rand() % (b-a))+ a; 要取得[a,b]的隨機整數,使用(rand() % (b-a+1))+ a; 要取得(a,b]的隨機整數,使用(rand() % (b-a))+ a + 1; */ return (rand()%90000)+10000; } //暴力遞迴 int Process(string input, int index){ //只有空串時會遇到這種情況,所以返回唯一的一種情況,空串 if(index==input.length()) return 1; //如果當前位置的值為0,則沒辦法轉成任何字母 if(input[index]=='0') return 0; //此時該位置不為0 ,則肯定有結果。res的值為當前的解以及第index+1到最後的那一段字串的結果的和 int res=Process(input, index+1); //此時遇到了字串的結尾,無法再繼續往下遞迴了,因此染回結果res if(index==input.length()-1) return res; //如果當前位置和其後面的位置的數字組合不大於26,說明兩個數可以組合出一種情況 //此時res要加上index+2到結尾的情況 if(((input[index]-'0')*10+input[index+1]-'0')<27) res+=Process(input, index+2); return res; } //動態規劃 int dp(string input){ //初始長度為input.length()+1,因為有可能會有空串的情況 //應該把該結果放在動態規劃陣列索引位置為input.length()的位置,因此初始化長度為input.length()+1 vector<int>con(input.length()+1); //把空串的情況存放在空串會發何時能的對應位置上 //空串的時候,只有一種結果,所以此時的值為1 con[input.length()]=1; //最後一位如果是0,則此處無解,否則此處是一種字母,結果為1 con[input.length()-1]=input[input.length()-1]=='0'?0:1; for(int i=input.length()-2; i>=0; i--){ if(input[i]=='0') con[i]=0; else con[i]=con[i+1]+ (((input[i]-'0')*10+(input[i+1]-'0'))<27?con[i+2]:0); } return con[0]; } int main(){ //把數字轉成字串 string input=to_string (CreatRandomNum()); //暴力遞迴 //cout<<Process(input, 0)<<endl; //動態規劃 //cout<<dp(input)<<endl; cout<<input<<endl; Process(input, 0)==dp(input)?cout<<"good"<<endl:cout<<"fucking !!! fuck!!!"<<endl; return 0; }
雖然做出來了,但是感覺有點夾生。