动态规划思想计算最大公共子串(c++代码)

16 篇文章 0 订阅
16 篇文章 0 订阅

问题:     

     计算两个字符串的最大公共子串(longest common continue substring),
     注意不是子序列是子串,子串是要求字符之间是相连的,而序列则只要求是保持前后顺序不变.
     我们这里要求的是最长公共子串的长度.

思想:

设:C[i,j] = LCS(str1[1...i],str2[1...j]),
即C[i,j]表示序列str1[1...i]和str2[1...j]的最长公共子序列的长度,则 C[m,n] = LCS(str1,str2)就是问题的解(长度为m,n).
计算公式为:
if str1[i] == str2[j] then C[i,j] = C[i-1,j-1] +1;
else if str1[i] != str2[j] then C[i,j] =0.

代码:

完整代码已上传我的github,项目名DP,其中还有最大公共子序列最长回文子串的实现:https://github.com/yisun03/DP

LCS_CTN.h

//
// Created by yis on 2020/7/12.
//

#ifndef DYNAMIC_PROGRAMMING_LCS_CTN_H
#define DYNAMIC_PROGRAMMING_LCS_CTN_H


#include <string>
#include <vector>

using std::string;
using std::vector;

namespace yis
{
  class LCS_CTN
  {
    // 计算两个字符串的最大公共子串(longest common continue substring),
    // 注意不是子序列是子串,子串是要求字符之间是相连的,而序列则只要求是保持前后顺序不变.
    // 我们这里要求的是最长公共子串的长度.

  public:
    // 计算两个字符串的最长公共子串(连续子序列).
    // 计算公式为:
    // if str1[i] == str2[j] then C[i,j] = C[i-1,j-1] +1;
    // else if str1[i] != str2[j] then C[i,j] = 0.
    static int lcs_continue(string& str1, string& str2, int m, int n);
  };
}


#endif //DYNAMIC_PROGRAMMING_LCS_CTN_H

LCS_CTN.cpp

//
// Created by yis on 2020/7/12.
//

#include "LCS_CTN.h"

namespace yis
{
  int LCS_CTN::lcs_continue(string &str1, string &str2 ,int m, int n)
  {
    int biggest = 0;
    vector<vector<int>> dp_table(m+1,vector<int>(n+1));
    for(int i = 0; i < m+1; ++i)
    {
      for(int j = 0; j < n+1; ++j)
      {
        if(i == 0 || j == 0)
        {
          dp_table[i][j] = 0;
        }
        else if(str1[i-1] == str2[j-1])
        {
          dp_table[i][j] = dp_table[i-1][j-1] +1;
          biggest = dp_table[i][j] > biggest ? dp_table[i][j] : biggest;
        }
        else
        {
          dp_table[i][j] = 0;
        }
      }
    }
    return biggest;
  }
}

main.cpp

//
// Created by yis on 2020/7/12.
//

#include <iostream>
#include "LCS_CTN.h"

int main()
{
  string str3 = "asdfas";
  string str4 = "werasdfaswer";

  std::cout << "str3 和str4的最长公共子串为:\n" << yis::LCS_CTN::lcs_continue(str3,str4,str3.length(),str4.length());
  std::cout << std::endl;
  return 0;
}

实验结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yisun03

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值