字符串的交错组成

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值