欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

LCS最长公共子序列【c++】

程序员文章站 2022-07-12 08:56:08
...

题目描述:

我们有两个字符串m和n,如果它们的子串a和b内容相同,则称a和b是m和n的公共子序列。子串中的字符不一定在原字符串中连续。
例如字符串“abcfbc”和“abfcab”,其中“abc”同时出现在两个字符串中,因此“abc”是它们的公共子序列。此外,“ab”、“af”等都是它们的字串。
现在给你两个任意字符串(不包含空格),请帮忙计算它们的最长公共子序列的长度

输入描述:

输入包含多组数据。
每组数据包含两个字符串m和n,它们仅包含字母,并且长度不超过1024

输出描述:

对应每组输入,输出最长公共子序列的长度。

示例:

输入
abcfbc abfcab
programming contest
abcd mnp
输出
4
2
0

解题思路:

1、一个简单的例子:
LCS最长公共子序列【c++】
解释:
1、填表
a和a的最大公共子串数目为1
a和ab的最长公共子串数目为1
……
ac和a的最长公共子串为1
ac和ab的最长公共子串为1
……
以此类推计算上述该表
2、推导状态转移方程
设上述二维数组为dp[5][6]
右下角为最长公共子序列长度及题解
状态转移方程为:
dp[i][j]=dp[i-1][j-1]+1 (a[i]=b[j])
dp[i][j]=max(dp[i-1][j],dp[i][j-1])

代码:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
	string A, B;
	while (cin >> A >> B)
	{
		int alen = A.length();
		int blen = B.length();
		vector<vector<int>>dp(alen, vector<int>(blen, 0));
		/*if (A[0] == B[0])
		{
			dp[0][0] = 1;
		}
		else
		{
			dp[0][0] = 0;
		}*/
		dp[0][0] = (A[0] == B[0]) ? 1 : 0;
		for (int i = 1; i < alen; i++)
		{
			dp[i][0] = (A[i] == B[0]) ? 1 : 0;
			dp[i][0] = max(dp[i - 1][0], dp[i][0]);
		}
		for (int j = 1; j < blen; j++)
		{
			dp[0][j] = (A[0] == B[j]) ? 1 : 0;
			dp[0][j] = max(dp[0][j-1], dp[0][j]);
		}
		for (int i = 1; i < alen; i++)
		{
			for (int j = 1; j < blen; j++)
			{
				dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
				if (A[i] == B[j])
				{
					dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1);
				}
			}
		}
		cout << dp[alen - 1][blen - 1]<<endl;
	}
	return 0;
}

链接:https://www.nowcoder.com/questionTerminal/9ae56e5bdf4f480387df781671db5172
来源:牛客网

相关标签: 日常练习