LCS(最长连续子序列+最长连续字串)
2017-05-17 21:32
323 查看
最长公共子串(LCS),有三种情况:
1.公共子串的元素必须相邻.
2.公共子串的元素可以不相邻。
3. 求多个字符串的最长公共子串。
第一个,公共子串的元素必须相邻.
解法就是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0。然后求出对角线最长的1序列,其对应的位置就是最长匹配子串的位置.
其中,将dp[i][j]的左上角dp[i-1][j-1]设置比它大一(有利于最后统计)。
求公共子串的元素可以不相邻问题。
用动态规划法,用二维数组统计两个字串的比较结果。
1、序列s1和序列s2
·长度分别为m和n;
·创建1个二维数组dp[m.n];
·初始化L数组内容为0
·m和n分别从0开始,m++,n++循环:
- 如果s1[m] = s2
,则dp[m,n] = dp[m - 1, n -1] + 1;
- 如果s1[m] != s2
,则dp[m,n] = max{dp[m,n - 1],dp[m - 1, n]}
·最后从L[m,n]中的数字一定是最大的,且这个数字就是最长公共子序列的长度
·从数组L中找出一个最长的公共子序列
2、从数组L中查找一个最长的公共子序列
i和j分别从m,n开始,递减循环直到i = 0,j = 0。其中,m和n分别为两个串的长度。
·如果s1[i] == s2[j],则将str[i]字符插入到子序列内,i–,j–;
·如果s1[i] != s2[j],则比较dp[i,j-1]与dp[i-1,j],dp[i,j-1]大,则j–,否则i–;(如果相等,则任选一个)
1.公共子串的元素必须相邻.
2.公共子串的元素可以不相邻。
3. 求多个字符串的最长公共子串。
第一个,公共子串的元素必须相邻.
解法就是用一个矩阵来记录两个字符串中所有位置的两个字符之间的匹配情况,若是匹配则为1,否则为0。然后求出对角线最长的1序列,其对应的位置就是最长匹配子串的位置.
其中,将dp[i][j]的左上角dp[i-1][j-1]设置比它大一(有利于最后统计)。
#include <cstdio> #include <string> #include <algorithm> #include <cstring> #include <iostream> using namespace std; int main()///求最长公共连续子串 { int dp[110][110]; string s1="21232523311324"; string s2="312123223445"; char p[110]; int len1=s1.length(); int len2=s2.length(); int st=0,ed=0; int len=0; for(int i=0; i<len1; i++) { for(int j=0; j<len2; j++) { if(s1[i]==s2[j]) { if(i==0||j==0) dp[i][j]=1; else { dp[i][j]=dp[i-1][j-1]+1; } } else { dp[i][j]=0; } if(dp[i][j]>len) { len=dp[i][j]; ed=j; } } } st=ed-len+1; for(int i=0; i<len1; i++) { for(int j=0; j<len2; j++) { printf("%d ",dp[i][j]); } cout<<endl; } printf("公共字串:\n"); for(int i=st; i<=ed; i++) { printf("%c",s2[i]); } cout<<endl; return 0; }
求公共子串的元素可以不相邻问题。
用动态规划法,用二维数组统计两个字串的比较结果。
1、序列s1和序列s2
·长度分别为m和n;
·创建1个二维数组dp[m.n];
·初始化L数组内容为0
·m和n分别从0开始,m++,n++循环:
- 如果s1[m] = s2
,则dp[m,n] = dp[m - 1, n -1] + 1;
- 如果s1[m] != s2
,则dp[m,n] = max{dp[m,n - 1],dp[m - 1, n]}
·最后从L[m,n]中的数字一定是最大的,且这个数字就是最长公共子序列的长度
·从数组L中找出一个最长的公共子序列
2、从数组L中查找一个最长的公共子序列
i和j分别从m,n开始,递减循环直到i = 0,j = 0。其中,m和n分别为两个串的长度。
·如果s1[i] == s2[j],则将str[i]字符插入到子序列内,i–,j–;
·如果s1[i] != s2[j],则比较dp[i,j-1]与dp[i-1,j],dp[i,j-1]大,则j–,否则i–;(如果相等,则任选一个)
#include <cstdio> #include <string> #include <algorithm> #include <cstring> #include <iostream> using namespace std; int main()///求最长公共连续子序列 { int dp[100][100]; string s1="ABCBDAB";///找出两者的最长公共不连续序列 string s2="BDCABA"; int len1=s1.length(); int len2=s2.length(); memset(dp,0,sizeof(dp)); for(int i=1; i<=len1; i++) { for(int j=1; j<=len2; 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]); } } } for(int i=0; i<=len1; i++) { for(int j=0; j<=len2; j++) printf("%d ",dp[i][j]); cout<<endl; } for(int i = len1, j = len2; i >= 1 && j >= 1;) { if(s1[i - 1] == s2[j - 1]) { cout << s1[i - 1] << " ";//倒序打印的 i--; j--; } else { // if(dp[i][j -1] >= dp[i - 1][j])//打印:B A D B if(dp[i][j -1] > dp[i - 1][j]) //打印:A B C B { j--; } else { i--; } } } cout << endl; cout<<dp[len1][len2]<<endl; return 0; }
相关文章推荐
- 最长公共字串(LCS)最长连续公共字串(LCCS)
- HDU 3308 线段树单点更新+区间查找最长连续子序列
- 最长连续子序列
- 最长连续子序列
- LIS(最长递增子序列)和LCS(最长公共子序列)的总结
- HDU 3308——LCIS(线段树,区间合并,最长连续递增子序列)
- HDU 3308 线段树。。最长连续上升子序列
- 【最长连续子序列和】三种复杂度的算法
- 最长连续递增子序列
- hdu1069-最长连续上升子序列
- Codeforces Round #335 (Div. 2) C. Sorting Railway Cars 最长连续上升子序列
- (DP6.1.4.1)UVA 111 History Grading(最长递增子序列LIS 的LCS 解法)
- 个人模板 最长公共连续子序列
- 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列
- 算法设计 - LCS 最长公共子序列&&最长公共子串 &&LIS 最长递增子序列
- 求最长连续字串
- 最长公共子序列(LCS)和最长公共连续子串
- Longest Consecutive Sequence 最长连续子序列
- 动态规划 最长公共子序列LCS、最长公共连续子串、最长重复子串
- FZU2216 最长连续子序列