动态规划---剑指offer面试题46--把数字翻译成字符串

题目

给定一个数字,按照如下规则翻译成字符串:

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;
}
 

猜你喜欢

转载自blog.csdn.net/qq_34793133/article/details/81395455
今日推荐