算法设计与分析之最长公共子序列

LCS是一种用于找到两个序列最长公共子序列的计算机科学问题,常用于数据比较和生物信息学。动态规划的解决方案以O(n^2)的时间和空间复杂度计算,可以通过回溯找到具体的子序列。此算法也应用于版本控制,如Git。
摘要由CSDN通过智能技术生成

简介

最长公共子序列(LCS)是一个在一个序列集合中(通常为两个序列)用来查找所有序列中最长子序列的问题。一个数列 ,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则称为已知序列的最长公共子序列。 [1]
最长公共子序列问题是一个经典的计算机科学问题,也是数据比较程序,比如Diff工具,和生物信息学应用的基础。它也被广泛地应用在版本控制,比如Git用来调和文件之间的改变。

算法

动态规划的一个计算两个序列的最长公共子序列的方法如下:
以两个序列 X、Y 为例子:
设有二维数组f[i,j] 表示 X 的 i 位和 Y 的 j 位之前的最长公共子序列的长度,则有:
f[1][1] = same(1,1);
f[i,j] = max{f[i-1][j -1] + same(i,j),f[i-1,j],f[i,j-1]};
其中,same(a,b)当 X 的第 a 位与 Y 的第 b 位相同时为“1”,否则为“0”。
此时,二维数组中最大的数便是 X 和 Y 的最长公共子序列的长度,依据该数组回溯,便可找出最长公共子序列。
该算法的空间、时间复杂度均为O(n^2),经过优化后,空间复杂度可为O(n)

具体实现代码

#include <iostream>
#include <cstring>
using namespace std;
const int N = 1024;
int c[N][N], b[N][N];
char s1[N], s2[N];
int len1, len2;
void LCS()
{
	for (int i = 1; i <= len1; i++) {
		for (int j = 1; j <= len2; j++) {
			if (s1[i - 1] == s2[j - 1]) { 
				c[i][j] = c[i - 1][j - 1] + 1;
				b[i][j] = 1;//左上角
			}
			else {
				if (c[i][j - 1] >= c[i - 1][j]) {
					c[i][j] = c[i][j - 1];//上
					b[i][j] = 2;
				}
				else {
					c[i][j] = c[i - 1][j];//左
					b[i][j] = 3;
				}
			}
		}
	}
}
void LCS_PRINT(int i, int j)
{
	if (i == 0 || j == 0) {
		return;
	}
	if (b[i][j] == 1) {
		LCS_PRINT(i - 1, j - 1);
		cout << s1[i - 1];
	}
	else if (b[i][j] == 2) {
		LCS_PRINT(i, j - 1);
	}
	else {
		LCS_PRINT(i - 1, j);
	}
}
int main()
{
	cout << "请输入X字符串" << endl;
	cin >> s1;
	cout << "请输入Y字符串" << endl;
	cin >> s2;
	len1 = strlen(s1);
	len2 = strlen(s2);
	for (int i = 0; i <= len1; i++) {
		c[i][0] = 0;
	}
	for (int j = 0; j <= len2; j++) {
		c[0][j] = 0;
	}
	LCS();
	cout << "s1与s2的最长公共子序列的长度是:" << c[len1][len2] << endl;
	cout << "s1与s2的最长公共子序列是:";
	LCS_PRINT(len1, len2);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

编程初学者01

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

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

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

打赏作者

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

抵扣说明:

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

余额充值