C++两字符串的最长公共子序列的个数及打印出最长公共子序列

该博客介绍了如何使用动态规划解决C++中寻找两个字符串的最长公共子序列问题。通过一个二维数组记录不同情况下的最长公共子序列长度,并提供了两种打印最长公共子序列的方法。动态规划状态转移方程基于字符是否相等来更新数组值,最终得到最长公共子序列的长度。

输入两字符串,输出最长的公共子序列长度。

采用动态规划思想。

假设字符串a长度为n,字符串b的长度为m,
使用一个二维数组arr[n+1][m+1]来记录每种情况下最长公共子序列的长度。

初始状态:字符串a空元素,字符串b空元素。这样的情况就填0.也就是二维数组首行首列全为0.
假设:
a{a,b,c,d}
b{b,c,a,d}

在这里插入图片描述

行 i 是字符串a的元素,列 j 是字符串b的元素

状态转换方程:如果这个二维数组中的i行字符等于j列中字符的情况,那么arr[i][j]就等于它的左上角arr[i - 1][j - 1]那个地方的值加一。如下图:
在这里插入图片描述

如果不相等,就从正上或者左边的元素里二选大。如下图

在这里插入图片描述

最终状态:字符串a长度为n,以及字符串b长度为m的情况下最长公共子序列,也就是二维数组最后一个元素arr[n][m].

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

void func(vector<char> a, vector<char> b, int n
要实现输入多组字符串数据(以 '#' 号结束),并输每组字符串的最长匹配子序列长度,可以使用动态规划的方法来解决最长公共子序列(LCS)问题。以下是实现该功能的 C++ 代码: ```cpp #include <iostream> #include <string> #include <vector> // 计算字符串最长公共子序列长度 int longestCommonSubsequence(const std::string& str1, const std::string& str2) { int m = str1.length(); int n = str2.length(); std::vector<std::vector<int>> dp(m + 1, std::vector<int>(n + 1, 0)); for (int i = 1; i <= m; ++i) { for (int j = 1; j <= n; ++j) { if (str1[i - 1] == str2[j - 1]) { dp[i][j] = dp[i - 1][j - 1] + 1; } else { dp[i][j] = std::max(dp[i - 1][j], dp[i][j - 1]); } } } return dp[m][n]; } int main() { std::string str1, str2; while (true) { std::cin >> str1; if (str1 == "#") { break; } std::cin >> str2; int length = longestCommonSubsequence(str1, str2); std::cout << length << std::endl; } return 0; } ``` ### 代码解释 1. **`longestCommonSubsequence` 函数**:该函数使用动态规划的方法计算字符串最长公共子序列长度。它创建一个二维数组 `dp`,其中 `dp[i][j]` 表示 `str1` 的前 `i` 个字符 `str2` 的前 `j` 个字符的最长公共子序列长度。 2. **`main` 函数**:在 `main` 函数中,程序不断读取输入的字符串对,直到遇到 '#' 号为止。对于每对字符串,调用 `longestCommonSubsequence` 函数计算它们的最长公共子序列长度,并输结果。 ### 复杂度分析 - **时间复杂度**:$O(m * n)$,其中 $m$ $n$ 分别是个输入字符串长度。 - **空间复杂度**:$O(m * n)$,主要用于存储动态规划的二维数组。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值