最长公共子序列与最长公共子串以及他们的打印(dp)
来源:互联网 发布:windows pe如何分区 编辑:程序博客网 时间:2024/05/01 17:59
1.最长公共子序列:两个序列都出现过并且出现顺序与母串保持一致,我们将其称为公共子序列,最长公共子序列(Longest Common Subsequence, LCS)是其中最长的。
c[i,j]=⎧⎩⎨⎪⎪0c[i−1,j−1]+1max(c[i,j−1],c[i−1,j])i=0 or j=0i,j>0 and xi=yji,j>0 and xi≠yj
两字符相等时左上角的数加一,否则取左边和上边最大的;
寻找方法:以图说明
例子:
abcfbc abfcabprogramming contest abcd mnp下面是代码:(打印路径的方法)
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;char a[1000],b[1000];//两个序列int dp[1000][1000];//记录序列的长度struct node{ char q;//当前点的字符 int x,y;//上一个点的坐标} cun[1000][1000];//记录每个点的路径char cun2[1000];//存储路径int main(){ while(~scanf("%s%s",a+1,b+1))//不从零开始,方便操作 { memset(dp,0,sizeof(dp)); int i,j; int la=strlen(a+1),lb=strlen(b+1); for(i=1; i<=lb; i++)//开始动归 { for(j=1; j<=la; j++) { if(a[j]==b[i])//两个字符相等时,记录左上角的坐标和当前的字符 dp[i][j]=dp[i-1][j-1]+1,cun[i][j].x=i-1,cun[i][j].y=j-1,cun[i][j].q=a[j]; else if(dp[i-1][j]>dp[i][j-1])//记录左方和上方中最大的数据 { dp[i][j]=dp[i-1][j]; cun[i][j].x=cun[i-1][j].x,cun[i][j].y=cun[i-1][j].y,cun[i][j].q=cun[i-1][j].q; } else if(dp[i-1][j]==dp[i][j-1])//左方和上方相等时,记录上方的数据 { dp[i][j]=dp[i][j-1]; cun[i][j].x=cun[i-1][j].x,cun[i][j].y=cun[i-1][j].y,cun[i][j].q=cun[i-1][j].q; } else { dp[i][j]=dp[i][j-1]; cun[i][j].x=cun[i][j-1].x,cun[i][j].y=cun[i][j-1].y,cun[i][j].q=cun[i][j-1].q; } } } printf("%d\012",dp[lb][la]); int xx=lb,yy=la,zz; for(i=0;i<dp[lb][la];i++)//开始回溯找路径 { cun2[i]=cun[xx][yy].q; zz=xx; xx=cun[xx][yy].x; yy=cun[zz][yy].y; } for(i=dp[lb][la]-1;i>=0;i--) printf("%c ",cun2[i]); printf("\n"); memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); } return 0;}
c[i,j]=⎧⎩⎨⎪⎪0c[i−1,j−1]+10i=0 or j=0xi=yjxi≠yj
只有字符相同时,才加一,其它情况都是零;
自己制作的图(可能不太好)
#include<stdio.h>#include<string.h>char a[1000],b[1000];//存储两个序列int dp[1000][1000];//子串的长度int main(){ while(~scanf("%s%s",a+1,b+1)) { memset(dp,0,sizeof(dp)); int i,j; int max=0;//记录最长的长度 int xx;//记录最长的子串的最后一个字符的坐标,因为子串是连续的所以找哪一个都一样,连续是很重要的 int la=strlen(a+1),lb=strlen(b+1); for(i=1; i<=lb; i++)//开始动归 { for(j=1; j<=la; j++) { if(a[j]==b[i]) { dp[i][j]=dp[i-1][j-1]+1; if(max<dp[i][j])//记录长度和坐标 { max=dp[i][j]; xx=i; } } else dp[i][j]=0; } } printf("%d\012",max); for(i=xx-max+1; i<=xx; i++)//因为是连续的,所以往后退max-1个就是它的开头; printf("%c ",b[i]); printf("\n"); memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); } return 0;}
有任何意见和好的方法,请留言,谢谢!
0 0
- 最长公共子序列与最长公共子串以及他们的打印(dp)
- 最长公共子序列与最长公共子串(DP)
- 最长公共子序列与最长公共子串(DP)
- 常考的经典算法--最长公共子序列(LCS)与最长公共子串(DP)
- 最长公共子序列 与 最长公共子串
- 最长公共子序列与最长公共子串
- 最长公共子序列 与 最长公共子串
- 最长公共子串与最长公共子序列
- 最长公共子序列与最长公共子串
- 最长上升子序列 最长公共子序列 最长公共子串 数字三角形 等简单DP以及变形
- 最长公共子序列--DP
- DP---最长公共子序列
- 最长公共子序列dp
- DP 最长公共子序列
- DP 最长公共子序列
- 最长公共子序列-DP
- 【DP】最长公共子序列。
- 最长公共子序列 DP
- 工厂模式
- Linux nano使用技巧
- C语言知识点学习之结构体成员变量后加冒号
- Swift 学习笔记 [3] 类 重载和构造器
- linux 串口serial设置登陆密码
- 最长公共子序列与最长公共子串以及他们的打印(dp)
- 时域的卷积等于频域的乘积证明
- android 关于Make sure the plugin is properly configured问题的解决办法
- linux搭建阿里云服务器
- android中文件下载
- MySQL本地登录失败
- 2016 review
- 欢迎使用CSDN-markdown编辑器
- 高性能网站架构之负载均衡 Nginx的安装