最长公共子序列-LCS
来源:互联网 发布:unity3d 点光源不亮 编辑:程序博客网 时间:2024/06/18 04:29
子序列
在数学中,某个序列的子序列是从最初序列通过去除某些元素但不破坏余下元素的相对位置(在前或在后)而形成的新序列。比如:ABCDEFGHI的一个子序列是ADFGI。
最长公共子序列
理解了子序列就能简单的理解最长公共子序列。就是对于两个序列,有一个序列三满足既是序列1的子序列也是序列2的子序列而且是满足这个条件的子序列中最长的一个,它就是序列1,2的最长公共子序列。
比如:BDCABA和ABCBDAB的最长公共子序列就是BCBA。
实现
最长公共子序列(Longest Common Subsequence, LCS)是一道非常经典的动态规划题,要学这个最好先对动态规划有一定了解。
设:
我们来看看怎么推出状态转移方程
首先,不难得出如下结论:
1. 如果
2. 如果
由上述结论,我们设dp[i][j]为
以BDCABA和ABCBDAB为例,我们看看它的递推过程
代码模板
int LCS(char *str1, char *str2){ int len1=strlen(str1); int len2=strlen(str2); memset(dp,0,sizeof(dp); for(int i=1;i<=len1;i++) { for(int j=1;j<=len2;j++) { if(str1[i-1]==str2[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[len1][len2];}
例题
给出两个字符串,求出其最长公共子序列及其长度。
代码:
#include <bits/stdc++.h>using namespace std;#define time_ (printf("%.6f\n", double(clock())/CLOCKS_PER_SEC))typedef long long ll;const int maxn = 1e3+5;int dp[maxn][maxn];//记录dp[i][j]是从哪递推过来的//-1是dp[i-1][j-1],0是dp[i][j-1],1是dp[i-1][j]int st[maxn][maxn];char str1[maxn],str2[maxn];void PrintLCS(int i,int j){ if(i==0 || j==0) return; if(st[i][j]==-1) { PrintLCS(i-1,j-1); printf("%c",str1[i-1]); } else if(st[i][j]==0) { PrintLCS(i,j-1); } else { PrintLCS(i-1,j); }}void LCS(){ int len1=strlen(str1); int len2=strlen(str2); memset(dp,0,sizeof(dp)); for(int i=1;i<=len1;i++) { for(int j=1;j<=len2;j++) { if(str1[i-1]==str2[j-1]) //这里是因为dp下标是从1开始,str1和str2的下标是从0开始 { dp[i][j] = dp[i-1][j-1]+1; st[i][j] = -1; } else if(dp[i][j-1]>dp[i-1][j]) { dp[i][j] = dp[i][j-1]; st[i][j] = 0; } else { dp[i][j] = dp[i-1][j]; st[i][j] = 1; } } } printf("%d\n",dp[len1][len2]); PrintLCS(len1,len2); printf("\n");}int main(){ gets(str1); gets(str2); LCS(); return 0;}
这里为什么是BDAB而不是我上面递推图中的BCBA,大家可以看我代码思考一下,应该很容易思考出来。
其实是else if(dp[i][j-1]>dp[i-1][j])这一句的问题。
- LCS:最长公共子序列
- LCS---最长公共子序列
- 最长公共子序列 LCS
- LCS -- 最长公共子序列
- LCS最长公共子序列
- 最长公共子序列LCS
- LCS-最长公共子序列
- 最长公共子序列 LCS
- 最长公共子序列(LCS)
- 最长公共子序列(LCS)
- 最长公共子序列LCS
- LCS最长公共子序列
- 最长公共子序列LCS
- 最长公共子序列 LCS
- LCS最长公共子序列
- 最长公共子序列(LCS)
- 最长公共子序列LCS
- 最长公共子序列LCS
- [项目实训]6.2 VJ整体的html页面的完善
- LeetCode之路:409. Longest Palindrome
- Android官方多媒体API Mediacodec翻译(一)
- Swing系列之控件一
- jQuery
- 最长公共子序列-LCS
- 牛腩新闻系统前台设计
- C语言的数据类型
- 查看Android签名
- qwb与矩阵 【DP】+【输入挂】
- iostream整理
- LeetCode532. K-diff Pairs in an Array
- 集群中配置多台计算机之间ssh无密码登录的一种简便方法
- 面试题22. 栈的压入、弹出序列