*description:字符串的交錯組成
* 給定三個字符串str1、str2、aim,如果aim包含且僅包含來自
* str1和str2的所有字符,且屬於str1的字符之間保持其在str1中順序,
* 屬於str2的字符也保持其在str2中的順序,稱aim是str1和str2的交錯組成
* 實現函數,判斷aim是否是str1和str2的交錯組成
**************************************************************************************/
#include<iostream>
#include<string>
#include<vector>
using namespace std;
//方法:時間複雜度O(M*N),空間複雜度O(M*N)
//經典動態規劃問題,創建布爾數組dp[M+1][N+1]
//dp[i][j]代表aim[0...i+j-1]是否爲str1[0...i-1]和str2[0...j-1]的交錯組成
//dp[0][0]=true,空串是兩空串的交錯組成
//dp[i][0]:aim[0...i-1]是否等於str1[0...i-1]
//dp[0][j]:aim[0...j-1]是否等於str2[0...j-1]
//dp[i][j]:下面4種情況的最小
// 1.dp[i-1][j] && str1[i-1]==aim[i+j-1]
// 2.dp[i][j-1] && str2[j-1]==aim[i+j-1]
//得到dp之後,右下角元素即爲結果。
bool isCross(string str1, string str2, string aim)
{
int M = str1.size();
int N = str2.size();
if (aim.size() != M + N)
return false;
vector<vector<bool>> dp(M+1, N+1);
dp[0][0] = true;
for (int i = 1; i < M+1; i++)
{
if (str1[i-1] == aim[i-1])
dp[i][0] = true;
else
{
for (int k = i; k < M+1; k++)
dp[k][0] = false;
break;
}
}
for (int j = 1; j < N+1; j++)
{
if (str2[j-1] == aim[j-1])
dp[0][j] = true;
else
{
for (int k = j; j < N+1; j++)
dp[0][j] = false;
break;
}
}
for (int i = 1; i < M+1; i++)
{
for (int j = 1; j < N+1; j++)
{
dp[i][j] = (dp[i-1][j] && str1[i-1]==aim[i+j-1])
|| (dp[i][j-1] && str2[j-1]==aim[i+j-1]);
}
}
return dp[M][N];
}
int main_10()
{
string str1 = "AB";
string str2 = "12";
string aim = "A12B";
cout << isCross(str1, str2, aim);
return 0;
}