动态规划C++实现--字符串的交错组成

题目:字符串的交错组成

       给定三个字符串 str1, str2 和 aim,如果 aim 包含仅包含来自 str1 和 str2的所有字符,而且在 aim 中属于str1的字符之间保持原来在 str1 的顺序,属于str2的字符之间保持原来 str2 的顺序,那么称 aim 是 str1 和 str2的交错组成。实现一个函数,判断aim是否是 str1 和 str2 交错组成。

-----------------------------------------------------------------------------------------------------------------

说明:

        原文作者利用Java进行实现,这里运用C++进行实现,供大家参考。

举例:

      str1 = "AB", str2 = "12",那么"AB12"、"A1B2"、"A12B"、"12AB" 和 "1AB2"都是 str1 和 str2的交错组成。

解答:

        如果str1的长度为M, str2的长度为N,可以利用经典的动态规划的方法可以达到时间复杂度为O(MN), 额外空间复杂度为O(MN)。

方法:aim的长度一定为 M+N,否则返回 false. 生成(M+1)x(N+1)的布尔类型的矩阵dp, 

          dp[i][j]表示 aim[0...i+j-1] 能否被 str1[0...i-1] 和 str2[0...j-1]交错组成。

          从左到右,从上到下计算,结果即为 dp[M][N]的值

更新策略:

        1. dp[0][0] = true;

        2. 矩阵dp第一列 dp[0...M-1][0] , dp[i][0] 表示 aim[0...i-1] 能否被 str1[0...i-1]组成,若

           aim[0...i-1] == str1[0...i-1],dp[i][0] = true ;

        3. 矩阵dp第一行 dp[0][0...N-1],dp[0][j] 表示 aim[0...j-1] 能否被 str2[0...j-1]组成,若

           aim[0...j-1] == str2[0..j-1], dp[0][j] = true;

        4. 其他位置的更新:

            dp[i][j] 的更新依赖于 dp[i-1][j] 与 dp[i][j-1]的结果,现做以下判断:

            (1) dp[i-1][j] 代表 aim[0..i+j-2] 能否被 str1[0...i-2] 和 str2[0...j-1]交错组成,如果可以(dp[i-1][j] = true),再在满足

                 str1[i-1] == aim[i+j-1] 则 dp[i][j] = true.

            (2) dp[i][j-1] 代表 aim[0..i+j-2] 能否被 str1[0...i-1] 和 str2[0...j-2]交错组成,如果可以 (dp[i][j-1] = true),再在满足

                 str2[j-1] == aim[i+j-1] 则 dp[i][j] = true.

            (3) 若(1)(2)均不满足,则 dp[i][j] = false.

-------------------------------------------------------------------------------------------------------------------------------------

代码如下:

// 字符串的交错组成<动态规划> <复杂度0(M*N)>
#include
using namespace std;
bool isCross1(string str1, string str2, string aim);

int main(){
    string str1, str2, aim;
    cout<<"第一个字符串:"; cin >> str1;
    cout<<"第二个字符串:"; cin >> str2;
    cout<<"目标字符串:";  cin >> aim;
    bool result = isCross1(str1, str2, aim);
    cout<<"判断结果为:"<< result;
    return 0;
}

bool isCross1(string str1,string str2, string aim){
    int row = str1.size() + 1;
    int col = str2.size() + 1;
    vector> dp(row, vector(col, false));
    if(aim.size() != (str1.size()+str2.size())){
        return false;
    }
    dp[0][0] = true;
    for(int i = 1; i < row; i++){
        if(str1[i-1] != aim[i-1]){
            break;
        }
        dp[i][0] = true;
    }
    for(int j = 1; j < col; j++){
        if(str2[j-1] != aim[j-1]){
            break;
        }
        dp[0][j] = true;
    }
    for(int i = 1; i < row; i++){
        for(int j = 1; j < col; j++){
            if(str1[i-1] == aim[i+j-1] && dp[i-1][j]){
                dp[i][j] = true;
            }
            if(str2[j-1] == aim[i+j-1] && dp[i][j-1]){
                dp[i][j] = true;
            }
        }
    }
    return dp[row - 1][col - 1];
}
/* input
ABCD
1234
A12B34CD
*/
/*
1
*/

编译器:codeblocks

输入:

动态规划C++实现--字符串的交错组成_第1张图片

输出:

动态规划C++实现--字符串的交错组成_第2张图片


你可能感兴趣的:(动态规划)