刷题----最长公共子序列

最长公共子序列要区分与最长公共字串,最长公共序列,字符串不一定是连续的,如ss1=abcde与ss2=acfe,公共序列为ace,关键点是字符串不一定连续

最长公共字串,简单处理可以用遍历处理

动态规划处理,重点是推导状态转移方程,由下到上,由少到多。设两个串的坐标为i j

当ss1[i] == ss2[j] ---->p[i][j] = ss1[i-1]+1

ss1[i] != ss2[j]  ----->p[i][j] = max(ss1[i-1][j],ss2[i][j-1])

int main()
{
    //求两个字符串最长公共子序列
    string ss1 = "abcde";
    string ss2 = "acfe";
    int s1Len = ss1.length();
    int s2Len = ss2.length();
    //动态生成二维矩阵
    int **p = new int*[s1Len + 1];
    for (int i = 0; i < (s1Len + 1); i++) {
        p[i] = new int[s2Len + 1];//每一行增加s2长度的列
    }
    //初始化增加的0行和0列,值为0
    for (int i = 0; i <= s1Len; ++i) {
        p[i][0] = 0;
    }
    for (int j = 0; j <= s2Len; ++j) {
        p[0][j] = 0;
    }
    //递推公式实现i == j --->上一个值加1;不相等时,取上面两个值的大者
    for (int i = 1; i <= s1Len; i++) {
        for (int j = 1; j <= s2Len; j++) {
            if (ss1[i-1] == ss2[j-1]) {
                p[i][j] = p[i - 1][j] + 1;
            }
            else
            {
                p[i][j] = max(p[i - 1][j], p[i][j - 1]);
            }
        }
    }
    //打印生成的整数相加矩阵
    for (int i = 0; i < s1Len + 1; i++) {
        for (int j = 0; j < s2Len + 1; j++) {
            cout << p[i][j];

        }
        cout << endl;
    }
    cout << "result is: " << p[s1Len][s2Len] << endl;

    //打印最长公共序列串
    //vector <int> strOut;
    //stack <int> outInfo;
    //outInfo.push(p[s1Len][s2Len]);
    //int m = s1Len;
    //int n = s2Len;
    //while (m > 0 && n > 0)
    //{
    //    if (ss1[m -1] == ss2[n-1]) {
    //        if (ss1[m - 1] == 0) {
    //            break;
    //        }
    //        cout << ss1[m - 1];
    //        m = m - 1;
    //        n = n - 1;
    //    }
    //    else
    //    {
    //        if (p[m - 1][n] >= p[m][n - 1]) {
    //            m = m - 1;
    //        }
    //        else if (p[m - 1][n] < p[m][n - 1])
    //        {
    //            n = n - 1;
    //        }
    //    }
    //}

    //删除申请的矩阵
    for (int i = 0; i < s1Len; i++) {
        delete[] p[i];
    }
    delete[] p;
    
    system("pause");
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值