题目
给定一个数字,按照如下规则翻译成字符串:
0->a
1->b
...
25->z
因此一个数字可能有多种翻译。例如,12258有5种不同的翻译,bccfi,bwfi,bczi,mcfi,mzi。
请实现一个函数,计算数字有多少种翻译方法。
思路
可以用递归解决,会发现子问题258 58都重复了。
自然想到可以用动态规划来解决,用f(i)来表示从第i位数字开始不同的翻译数目,
我们可以写出递推关系
g(i,i+1)表示第i位和i+1位拼起来的数字在10~25范围内,值为1,否则为0。
先多设一个f[5]=1,f[5]是假定的一个数,作用是便于动态规划的递推公式的通用)
f(4) = f(5)+g(4,5)*f(6)=1+0*1=0 (不妨设左起第一个字母从0开始编号,4是右边最后一个字母)
f(3) = f(4) + 0 = 1 (f(3) = f(4) + 0*f(5) = 1)
f(2) = f(3) + f(4) = 2 (f(2) = f(3) + 1*f(4)=2)
f(1) = f(2) + f(3) = 3
f(0) = f(1) + f(2) = 5
#include <iostream>
#include <string>
using namespace std;
_int64 getTranslationCount(const string& number)
{
const int length = number.size();
if (length <= 0)
return 0;
int *f = new int[length + 1];
int *g = new int[length];
/************************初始化************************/
f[length] = 1;
f[length - 1] = 1;
g[length - 1] = 0;
/************************初始化************************/
/******************************求g[]***********************/
for (int i = 0; i < length - 1; ++i)
{
int c1 = number[i] - '0';
int c2 = number[i + 1] - '0';
int DicIndex = c1 * 10 + c2;
if (DicIndex >= 10 && DicIndex <= 25)
g[i] = 1;
else
g[i] = 0;
}
/****************************求f[]**********************/
if (length > 1)
{
for (int j = length - 2; j >= 0; --j)
{
f[j] = f[j + 1] + g[j] * f[j + 2];
}
}
return f[0];
}
_int64 GettranslationCount(_int64 number)
{
if (number < 0)
return 0;
string numberToString = to_string(number);
return getTranslationCount(numberToString);
}
int main()
{
_int64 num; //8字节的整数,可表示的数字范围大
//关于常用的数据类型https://blog.csdn.net/qq_34793133/article/details/81407140
cout << "请输入待翻译的数字:\n";
cin >> num;
cout << GettranslationCount(num) << endl;
return 0;
}