21xrx.com
2024-12-23 00:03:56 Monday
登录
文章检索 我的文章 写文章
C++ 动态规划:字符串最长公共子序列
2023-07-05 21:55:51 深夜i     --     --
C++ 动态规划 字符串 最长公共子序列

字符串最长公共子序列是一道非常经典的问题,它的解法有很多种。其中最常用的方法是动态规划。在本篇文章中,我们将介绍使用 C++ 实现字符串最长公共子序列问题的动态规划算法。

首先,我们需要明确什么是字符串最长公共子序列。给定两个字符串 S1 和 S2,它们的最长公共子序列是一个新的字符串,它是 S1 和 S2 的某个子序列(可以不是连续的),且长度最长。

下面是 C++ 实现的动态规划算法:


int lcs(string s1, string s2) {

  int m = s1.length(), n = s2.length();

  int dp[m + 1][n + 1];

  for (int i = 0; i <= m; i++)

    for (int j = 0; j <= n; j++)

      dp[i][j] = 0;

  for (int i = 1; i <= m; i++)

    for (int j = 1; j <= n; j++) {

      if (s1[i - 1] == s2[j - 1])

        dp[i][j] = dp[i - 1][j - 1] + 1;

      else

        dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);

    }

  return dp[m][n];

}

这段代码的思路是使用一个二维数组 dp[m+1][n+1],其中 dp[i][j] 表示字符串 S1 的前 i 个字符和字符串 S2 的前 j 个字符的最长公共子序列的长度。最后返回 dp[m][n],即 S1 和 S2 的最长公共子序列的长度。

算法的实现过程也非常简单。我们首先初始化 dp 数组,然后循环计算 dp[i][j],当 S1[i-1] 等于 S2[j-1] 时,dp[i][j] 应该等于 dp[i-1][j-1] + 1,因为两个字符相同,所以它们都可以在最长公共子序列中。当 S1[i-1] 不等于 S2[j-1] 时,dp[i][j] 应该等于 dp[i-1][j] 和 dp[i][j-1] 中的较大值,因为一个字符无法同时出现在两个字符串的最长公共子序列中。

最后,我们可以调用 lcs 函数来计算两个字符串的最长公共子序列。例如:


string s1 = "ABCD", s2 = "ACDF";

int ans = lcs(s1, s2);

cout << ans << endl; // 输出 2

这段代码将输出 2,因为字符串 "AD" 是它们的最长公共子序列。

在实际运用中,字符串最长公共子序列问题有很多应用场景,比如 DNA 序列分析、版本控制等。动态规划算法是解决该问题的最常用的方法。在 C++ 中,我们可以通过简单的代码实现该算法,从而快速求解最长公共子序列问题。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复