动态规划只是递归的一种优化,凡是可以使用动态规划解决的问题基本上都可以使用递归的方法。下面是联系题
字符串的交错组成
【题目】
给定三个字符串str1、str2和aim。如果aim包含且仅包含来自str1和str2的所有字符,而且在aim中属于
str1的字符之间保持原来在str1中的顺序,属于str2的字符之间保持原来在str2中的顺序,那么称aim是
str1和str2的交错组成。实现一个函数,判断aim是否是str1和str2交错组成。
【举例】
str1=“AB”,str2=“12”。那么“AB12”、“A1B2”、“A12B”、“1A2B”和“1AB2”等等都是str1和str2交错组成。
代码:
递归:
#incldue <iostream>
#include <string>
using namespace std;
string cutlast(string str)
{
return string(str,0,str.length()-1);
}
bool iscross(string str1,string str2,string aim)
{
if(str1.empty()&&!aim.empty())
{
if(str2==aim)
return true;
}
if(str2.empty()&&!aim.empty())
{
if(str1==aim)
return true;
}
if(aim[aim.length()-1]==str1[str1.length()-1])
{
string str1c=cutlast(str1);
string aimc=cutlast(aim);
return iscross(str1c,str2,aimc);
}
if(str2[str2.length()-1]==aim[aim.length()-1])
{
string str2c=cutlast(str2);
string aimc=cutlast(aim);
return iscross(str1,str2c,aimc);
}
return false;
}
bool isCross(string str1,string str2,string aim)
{
if(str1.empty()||str2.empty()||aim.empty())
{
return false;
}
if(str1.length()+str2.length()!=aim.length())
return false;
return iscross(str1,str2,aim);
}
非递归:动态规划的方法
#include <iostream>
#include <string>
using namespace std;
bool isCross(string str1,string str2,string aim)
{//1、先判断输入参数是否有效
if(str1.empty()||str2.empty()||aim.empty())
return false;
int len1=str1.length();
int len2=str2.length();
if(len1+len2!=aim.length())
return false;
//开辟dp数组,dp[i][j]表示aim[i+j-1]可以由str1【0…i-1】和str2【0…j-1】交错组成
bool **dp=new bool*[len1+1];
for(int i=1;i<=len1+1;i++)
{
dp[i-1]=new bool[len2+1];
for(int j=1;j<=len2+1;j++)
dp[i-1][j-1]=false;
}
dp[0][0]=true;
//初始化dp数组的首行首列
for(int i=1;i<=len1;i++)
{
if(str1[i-1]!=aim[i-1])
break;
dp[i][0]=true;
}
for(int i=1;i<=len2;i++)
{
if(str2[i-1]!=aim[i-1])
break;
dp[0][i]=true;
}
for(int i=1;i<=len1;i++)
for(int j=1;j<=len2;j++)
{
if(( str1[i-1]==aim[i+j-1]&&dp[i-1][j])||(str2[j-1] == aim[i+j-1] &&dp[i][j-1]))
dp[i][j]=true;
}
return dp[len1][len2];
}