题目描述:
给定一个数字,我们按照如下规则把它翻译成字符串:0翻译成‘a’,1翻译成’b’…25翻译成’z’。一个数字可能有多个翻译,例如,12258有5种不同的翻译,分别是’bccfi’,’bwfi’,’bczi’,’mcfi’,’mzi’。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
动态规划:
举例来分析一下:“12258 的翻译种数”=“1225 的翻译种数”;“1225 的翻译种数”=“122 的翻译种数”+“12 的翻译种数”;“122 的翻译种数”=“12 的翻译种数”+“1 的翻译种数”;“12 的翻译种数”=“1 的翻译种数”;“1 的翻译种数=1”。
从以上的分析,我们可以看出,这个问题可以拆分成多个子问题来求解,并且子问题有重叠部分,状态转移方程如下:
f(i)={f(i−1)+f(i−2),0≤c(i−1,i)≤25,其他f(i)=f(i-1).
其中,f(i) 表示数字从左往右第 i 个的翻译种数,c(i-1, i) 表示数字从左往右第 i - 1 和第 i 个字符拼接后的数字(例如:12258 的 c(1, 2)=22)。
int getTranslationCount(int number)
{
if(number < 0)
return 0;
string number_str = to_string(number);
return getTransCnt(number_str);
}
int getTransCnt(const string& number)//string对象可能会非常长,应尽量避免拷贝,另外当函数无需修改引用形参时最好使用常量引用。
{
int len = number.length();
int *cnt = new int[len];//建立数组保存每一步的结果
memset(cnt,0,len);//全置0
int res = 0;
for(int i = len - 1; i >= 0; ++i)
{
res = 0;
if(i < len -1)
res = cnt[i+1];
else
res = 1;
if(i < len -1)
{
int digit1 = number[i] - '0';
int digit2 = number[i+1] - '0';
int converted = digit1 * 10 + digit2;
if(converted >= 10 && converted <= 25)
{
if( i < len -2)
res += cnt[i+2];
else
res += 1;
}
}
cnt[i] = res;
}
res = cnt[0];
delete[] cnt;
return res;
}