LCS(最长连续子序列+最长连续字串)
来源:互联网 发布:linux mount busy 编辑:程序博客网 时间:2024/05/18 01:22
最长公共子串(LCS),有三种情况:
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[n],则dp[m,n] = dp[m - 1, n -1] + 1;
- 如果s1[m] != s2[n],则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(最长连续子序列+最长连续字串)
- LCS 最长公共子序列问题(非连续的)
- 连续最长子序列
- 最长连续子序列
- 最长连续子序列
- 最长连续子序列
- 最长公共子序列(LCS)和最长公共连续子串
- 动态规划 最长公共子序列LCS、最长公共连续子串、最长重复子串
- 最长公共子序列(LCS)问题(非连续子序列)的两种解法
- 最长公共子序列(LCS)问题(连续子序列)的三种解法
- 最长公共子序列(LCS)问题(非连续子序列)的两种解法
- 最长公共子序列(连续)
- HDU 1231 (最长连续子序列)
- 最长上升连续子序列(LintCode)
- 最长公共子序列(不连续)
- 最长上升子序列(非连续)
- fjnu 最长连续子序列
- 最长连续子序列 DP
- Vue的过渡效果
- 四、StackPanel控件
- c++学习(三)
- Android中UI线程与子线程的通信
- SVN使用手册
- LCS(最长连续子序列+最长连续字串)
- Makefile相关规则
- ubuntu17.04 Redis安装与使用
- max模型修改小技巧(一)
- ant design+node.js+mongoose实现一个简单的注册登录功能
- win7 + 传统/boot 引导 + Ubuntu16.04.02 + U盘启动盘
- BZOJ 4720: [Noip2016]换教室
- jquery源码分析
- Hadoop前置环境的安装