数字字符串转换为字母组合的种类数 动态规划

来源:互联网 发布:c语言入门那本书好 编辑:程序博客网 时间:2024/05/16 02:05

1、问题描述:来源《算法与数据结构最优解》左程云著

给定一个字符串str,str全部由数字字符组成,如果str中某一个或某相邻两个字符组成的子串值在1-26之间,则这个子串可以转换为一个字母。规定"1"转换为"A","2"转换为"B",..."26"转换为"Z"。返回str转换的种类数


2、输入输出

str="1111",返回5;

str="01",返回0;

str="10",返回1


3、问题解析

1)这个问题是一个一维的问题,一般情况下比较好解决,本题的关键在于它是一个逆序的问题,从后往前推,dp[i]代表从第 i 位 到最后一位能够转换的种类数,这样dp[0]就是我们最终需要的答案。

2)接下来一个关键点就是递推式的推导。根据题目要求,如果str[i]是0的话,是没办法转换成字母的,那么dp[i]=0;之后看str[i]和str[i+1]是否可以组成一个字母,如果可以,那么dp[i]=dp[i+1]+dp[i+2];如果不可以,那么dp[i]=dp[i+1]。


4、下面是具体的代码实现

#include<iostream>#include<vector>#include<string>using namespace std;void getNum(string);int main() {string str;getline(cin, str);getNum(str);}void getNum(string str) {int len = str.length();if (len == 0) {cout << 0 << endl;return;}vector<int> dp(len);//dp[i]代表从i到len-1的转换的种类数,i: 0~len-3int i;//对dp[len-1]和dp[len-2]进行赋值if (str[len - 1] == '0') {dp[len - 1] = 0;if (len >= 2&&(str[len-2]=='1'||str[len-2]=='2')) {//10或者20dp[len - 2] = 1;}else if(len>=2){dp[len - 2] = 0;//00 或者 30....90}}else {dp[len - 1] = 1;if (len >= 2 && (str[len - 2] == '1' || str[len - 2] == '2')&&(str[len-1]>'0'&&str[len-1]<'7')) {// 11-26dp[len - 2] = 2;}else if (len >= 2&& str[len - 2] == '0') {//01-09dp[len - 2] = 0;}else if (len >= 2) {//其余情况dp[len - 2] = 1;}}//为其他的dp赋值for (i = len - 3; i >= 0; --i) {if (str[i] == '0')dp[i] = 0;else if ((str[i] == '1' || str[i] == '2') && (str[i + 1] > '0'&&str[i + 1] < '7')) {dp[i] = dp[i + 1] + dp[i + 2];}else {dp[i] = dp[i + 1];}}cout << dp[0] << endl;}