1. 程式人生 > >刷題 編寫一個函式,給出可以轉換的不同字串的個數。

刷題 編寫一個函式,給出可以轉換的不同字串的個數。

題目:

將給定的數轉換為字串,原則如下: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;
}

雖然做出來了,但是感覺有點夾生。