LCS-基础
2015-08-10 13:14
387 查看
最长公共子序列和最长公共连续子串:
最长公共连续子串(Longest CommonSubstring) 和最长公共子序列(LongestCommon Subsequence, LCS)的区别:子串(Substring)是串的一个连续的部分,子序列(Subsequence)则是从不改变序列的顺序,而从序列中去掉任意的元素而获得的新序列;更简略地说,前者(子串)的字符的位置必须连续,后者(子序列LCS)则不必。
比如:字符串 acdfg 和 akdfc
最长公共连续子串: df
最长公共子序列是: adf。
最长公共子序列
代码1:
#include<cstdio>
#include<cstring>
#define max(x,y) (x>y?x:y)
char ch1[1010],ch2[1010];
int dp[1010][1010];
int main()
{
while(scanf("%s%s",ch1,ch2)!=EOF)
{
memset(dp,0,sizeof(dp));
int len1=strlen(ch1);
int len2=strlen(ch2);
int i,j;
for(i=1;i<=len1;++i) //模板
{
for(j=1;j<=len2;++j)
{
if(ch1[i-1]==ch2[j-1])
dp[i][j]=dp[i-1][j-1]+1;
else
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
printf("%d\n",dp[len1][len2]);
}
return 0;
}代码2:
最长公共连续子串 代码:
最长公共连续子串(动态) 代码:
最长公共连续子串(Longest CommonSubstring) 和最长公共子序列(LongestCommon Subsequence, LCS)的区别:子串(Substring)是串的一个连续的部分,子序列(Subsequence)则是从不改变序列的顺序,而从序列中去掉任意的元素而获得的新序列;更简略地说,前者(子串)的字符的位置必须连续,后者(子序列LCS)则不必。
比如:字符串 acdfg 和 akdfc
最长公共连续子串: df
最长公共子序列是: adf。
最长公共子序列
代码1:
#include<cstdio>
#include<cstring>
#define max(x,y) (x>y?x:y)
char ch1[1010],ch2[1010];
int dp[1010][1010];
int main()
{
while(scanf("%s%s",ch1,ch2)!=EOF)
{
memset(dp,0,sizeof(dp));
int len1=strlen(ch1);
int len2=strlen(ch2);
int i,j;
for(i=1;i<=len1;++i) //模板
{
for(j=1;j<=len2;++j)
{
if(ch1[i-1]==ch2[j-1])
dp[i][j]=dp[i-1][j-1]+1;
else
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
printf("%d\n",dp[len1][len2]);
}
return 0;
}代码2:
#include<cstdio> #include<cstring> #define max(x,y) (x>y?x:y) int len1,len2; int dp[1010][1010]; int bj[1010][1010]; char ch1[1010],ch2[1010]; void LCS() //lcs最长公共子序列模板 { int i,j; for(i=1;i<=len1;++i) { for(j=1;j<=len2;++j) { if(ch1[i-1]==ch2[j-1]) { dp[i][j]=dp[i-1][j-1]+1; bj[i][j]=1; } else if(dp[i-1][j]>=dp[i][j-1]) { dp[i][j]=dp[i-1][j]; bj[i][j]=0; } else { dp[i][j]=dp[i][j-1]; bj[i][j]=2; } } } } void PRINTF(int i,int j) //输出最长公共子序列 { if(i==0||j==0) return ; if(bj[i][j]==1) { PRINTF(i-1,j-1); printf("%c",ch1[i-1]); } else if(bj[i][i]==0) PRINTF(i-1,j); else PRINTF(i,j-1); } int main() { int len; while(scanf("%s%s",ch1,ch2)!=EOF) { memset(dp,0,sizeof(dp)); //清零 memset(bj,0,sizeof(bj)); len1=strlen(ch1); len2=strlen(ch2); LCS(); len=dp[len1][len2]; //最长公共子序列的长度 printf("%d\n",len); PRINTF(len1,len2); //输出最长公共子序列 printf("\n"); } return 0; }
最长公共连续子串 代码:
//找出两个字符串的最长公共连续子串的长度 #include<cstdio> #include<cstring> char ch1[1010],ch2[1010]; char ch[1010]; //存放最大连续子串 int bj[1010][1010]; int len1,len2,max_len,xi,yj; void LCS_string() //最大连续子串长度 { int i,j; max_len = -1; for(i=1;i<len1+1;i++) { for(j=1;j<len2+1;j++) { if(ch1[i-1]==ch2[j-1]) bj[i][j]=bj[i-1][j-1]+1; else bj[i][j]=0; if(bj[i][j]>max_len) { max_len=bj[i][j]; xi=i; yj=j; } } } } void MAX_string() //求最大连续子串 { int n=max_len; int i,j; ch[n--]='\0'; i=xi-1; j=yj-1; while(i>=0&&j>=0) { if(ch1[i]==ch2[j]) { ch[n--]=ch1[i]; i--; j--; } else break; } } int main() { while(scanf("%s%s",ch1,ch2)!=EOF) { len1=strlen(ch1); len2=strlen(ch2); memset(ch,'\0',sizeof(ch)); memset(bj,0,sizeof(bj)); LCS_string(); printf("最大连续子串长度: %d\n",max_len); MAX_string(); printf("最大连续子串: %s\n",ch); } return 0; }
最长公共连续子串(动态) 代码:
//找出两个字符串的最长公共连续子串的长度 #include<cstdio> #include<cstring> int len1,len2,max_len,xi,yj; char ch1[1000],ch2[1000]; char ch[1010]; void LCS_string() { int i,j; int **bj = new int*[len1+1]; //动态申请的二维数组 for(i = 0; i < len1+1; i++) bj[i] = new int[len2+1]; for(i = 0; i < len1+1; i++) bj[i][0]=0; //第0列都初始化为0 for(j = 0; j < len2+1; j++) bj[0][j]=0; //第0行都初始化为0 max_len = -1; for(i = 1 ; i < len1+1 ; i++) { for(j = 1; j < len2+1; j++) { if(ch1[i-1]==ch2[j-1]) //只需要跟左上方的c[i-1][j-1]比较就可以了 bj[i][j]=bj[i-1][j-1]+1; else //不连续的时候还要跟左边的c[i][j-1]、上边的c[i-1][j]值比较,这里不需要 bj[i][j]=0; if(bj[i][j]>max_len) { max_len=bj[i][j]; xi=i; yj=j; } } } for(i = 0; i < len1+1; i++) //释放动态申请的二维数组 delete[] bj[i]; delete[] bj; } void MAX_string() //求最大连续子串 { int n=max_len; int i=xi-1,j=yj-1; ch[n--]='\0'; while(i>=0 && j>=0) { if(ch1[i]==ch2[j]) { ch[n--]=ch1[i]; i--; j--; } else //只要有一个不相等,就说明相等的公共字符断了,不连续了 break; } } int main() { while(scanf("%s%s",ch1,ch2)!=EOF) { len1=strlen(ch1); len2=strlen(ch2); memset(ch,'\0',sizeof(ch)); LCS_string(); printf("最长公共子串长度: %d\n",max_len); MAX_string(); printf("最长公共子串为: "); printf("%s\n",ch); } return 0; }
相关文章推荐
- N天测试网络视频会议系统
- 最长公共字串
- DP问题各种模型的状态转移方程
- LCS 最长公共子序列
- 最长公共子序列
- Two ways to solve the "Longest common subsequence" problem
- 最长公共子序列
- 算法之动态规划(LCS最长公共子序列, edit distance,交叉子串)
- LCS
- POJ 1080 - Human Gene Functions
- 最长公共子序列
- 【算法刷题】poj 1080 Human Gene Function
- 算法之插入、归并排序,最大公共子串lcs
- 【转】最大和子序列、最长递增子序列、最长公共子串、最长公共子序列、字符串编辑距离
- 动态规划(dynamic program)&& 最长公共子序列(LCS)
- HDU 1513 Palindrome
- UVA 10066 The Twin Towers
- UVA 10405 Longest Common Subsequence
- poj1159 —— 一个字符串,求最少插入几个字符可以组成回文
- 动态规划之最长公共子序列和编辑距离