LCS最长公共子序列
来源:互联网 发布:类似蝰蛇音效的软件 编辑:程序博客网 时间:2024/05/21 10:42
Procedure LCS_LENGTH(X,Y); begin m:=length[X]; n:=length[Y]; for i:=1 to m do c[i,0]:=0; for j:=1 to n do c[0,j]:=0; for i:=1 to m do for j:=1 to n do if x[i]=y[j] then begin c[i,j]:=c[i-1,j-1]+1; b[i,j]:="↖"; end else if c[i-1,j]≥c[i,j-1] then begin c[i,j]:=c[i-1,j]; b[i,j]:="↑"; end else begin c[i,j]:=c[i,j-1]; b[i,j]:="←" end; return(c,b); end;
图解
求LCS长度和LCS
[cpp] view plain copy #include <iostream> #include <cstring> using namespace std; int length_LCS(string s1,string s2,int **c,int **b,int m,int n) //输出LCS的长度 { /*处理特殊的0行和0列*/ for(int i=0;i<=m;i++) c[i][0]=0; for(int j=0;j<=n;j++) c[0][j]=0; /*处理其他行和列*/ for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { if(s1[i-1]==s2[j-1]) { c[i][j]=c[i-1][j-1]+1; b[i-1][j-1]=0; } else { if(c[i-1][j]>=c[i][j-1]) { c[i][j]=c[i-1][j]; b[i-1][j-1]=1; } else { c[i][j]=c[i][j-1]; b[i-1][j-1]=-1; } } } } return c[m][n]; } void Print_LCS(int **b,string x,int i,int j) //输出LCS序列 { if(i==0||j==0) return ; if(b[i-1][j-1]==0) { Print_LCS(b,x,i-1,j-1); cout<<x[i-1]; } else if(b[i-1][j-1]==1) { Print_LCS(b,x,i-1,j); } else Print_LCS(b,x,i,j-1); } int main() { string s1,s2; cout<<"请输入两个序列:"<<endl; cin>>s1>>s2; int m=s1.length(),n=s2.length(); int **c=new int*[m+1]; //动态分配二维数组 for(int i=0;i<=m;i++) c[i]=new int[n+1]; int **b=new int*[m]; //动态分配二维数组 for(int j=0;j<m;j++) b[j]=new int[n]; cout<<"LCS的长度:"<<length_LCS(s1,s2,c,b,m,n)<<endl; cout<<"打印其中的一个LCS:"; Print_LCS(b,s1,m,n); //此处最好的处理是释放空间 cout<<endl; return 0; }优化空间
事实上,数组元素c[i,j]的值仅由c[i-1,j-1],c[i-1,j]和c[i,j-1],所以只需要dp[2][n]的空间就行,利用滚动数组
if(s1[i] == s2[j]) dp[(i+1)%2][j+1] = dp[i%2][j]+1;
else dp[(i+1)%2][j+1] = max(dp[(i+1)%2][j], dp[i%2][j+1]);
结果为dp[n%2][n]
优化时间转化为最长递增子序列问题,O( n*log(n) )
注意到num[i][j]仅在A[i]==B[j]处才增加,对于不相等的地方对最终值是没有影响的。故而枚举相等点处可以对上述动态规划算法进行优化。
举例说明:
A:abdba
B:dbaaba
则1:先顺序扫描A串,取其在B串的所有位置:
2:a(2,3,5) b(1,4) d(0)。
3:用每个字母的反序列替换,则最终的最长严格递增子序列的长度即为解。
替换结果:532 41 0 41 532
最大长度为3.
#include <stdio.h> #include <ctype.h> #include <string.h> #include <iostream> #include <string> #include <math.h> #include <vector> #include <queue> #include <algorithm> using namespace std; const int maxn = 1501 ; vector<int> location[26] ; int c[maxn*maxn] , d[maxn*maxn] ; inline int get_max(int a,int b) { return a > b ? a : b ; } //nlogn 求lcs int lcs(char a[],char b[]) { int i , j , k , w , ans , l , r , mid ; for( i = 0 ; i < 26 ; i++) location[i].clear() ; for( i = strlen(b)-1 ; i >= 0 ; i--) location[b[i]-'a'].push_back(i) ; for( i = k = 0 ; a[i] ; i++) { for( j = 0 ; j < location[w=a[i]-'a'].size() ; j++,k++) c[k] = location[w][j] ; } d[1] = c[0] ; d[0] = -1 ; for( i = ans = 1 ; i < k ; i++) { l = 0 ; r = ans ; while( l <= r ) { mid = ( l + r ) >> 1 ; if( d[mid] >= c[i] ) r = mid - 1 ; else l = mid + 1 ; } if( r == ans ) ans++,d[r+1] = c[i] ; else if( d[r+1] > c[i] ) d[r+1] = c[i] ; } return ans ; } int main() { char a[maxn] , b[maxn] ; while (~scanf("%s%s",a,b)) { printf("%d\n",lcs(a,b)); } }
阅读全文
0 0
- LCS:最长公共子序列
- LCS---最长公共子序列
- 最长公共子序列 LCS
- LCS -- 最长公共子序列
- LCS最长公共子序列
- 最长公共子序列LCS
- LCS-最长公共子序列
- 最长公共子序列 LCS
- 最长公共子序列(LCS)
- 最长公共子序列(LCS)
- 最长公共子序列LCS
- LCS最长公共子序列
- 最长公共子序列LCS
- 最长公共子序列 LCS
- LCS最长公共子序列
- 最长公共子序列(LCS)
- 最长公共子序列LCS
- 最长公共子序列LCS
- Lesson 3 上机练习题——继承
- 看源码了解Gson excludeStrategy的使用
- UBUNTU安装faac
- opencv 手写选择题阅卷 (四)Android端 手机应用开发
- 展讯7715平台安卓7.0控制io口驱动
- LCS最长公共子序列
- Mybatis的mapper配置文件(一)
- 多态练习(声音模拟器)
- linux 安装nginx
- HDU-2222 Keywords Search (AC自动机入门)
- 习题6.4
- Android 7.0 pendingIntent bug(AlarmManager通过PendingIntent传递数据(跨进程数据传递
- 可以启动Tomcat,但是无法访问项目
- 1043. Is It a Binary Search Tree (25)(判断二叉树)