您的位置:首页 > 编程语言

编程之美3.3——类似——两个字符串的最长公共子序列(LCS)

2015-04-16 22:39 387 查看
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

#define MAXN 10001
char A[MAXN];
char B[MAXN];
int dp[MAXN][MAXN];
// 设Z为A和B的最长公共子序列,dp[i][j]表示A从位置i开始的后缀与
// B从位置j开始的后缀的最长公共子序列Z从位置k开始的后缀的长度
void fun1()
{
cin>>A>>B;
int i, j, m, n;
n = strlen(A);
m = strlen(B);
// 初始化,若一个序列为空,则最长子序列肯定为0
for (i=0; i<=n; i++)
dp[i][m] = 0;
for (j=0; j<=m; j++)
dp
[j] = 0;
for(i=n-1; i>=0; i--)
for(j=m-1; j>=0; j--)
{
if (A[i] == B[j])
// 若相等,则zk=Ai=Bj且A从位置i+1开始的后缀与B从位置j+1开始的后缀
// 的最长公共子序列是Z从位置k+1开始的后缀
dp[i][j]=dp[i+1][j+1]+1;
else
// 若不相等,则取两个最长公共子序列中长度较大的那个
dp[i][j]=max(dp[i][j+1], dp[i+1][j]);
}
for(i=0;i<=n;i++)
{
for(j=0;j<=m;j++)
printf("%d ",dp[i][j]);
printf("\n");
}
printf("%d\n", dp[0][0]);
}
int CalculateLcs(string s1,int p1E,string s2,int p2E)
{
if(p1E<0||p2E<0)
return 0;
if(s1[p1E]==s2[p2E])
{
return CalculateLcs(s1,p1E-1,s2,p2E-1)+1;
}
else
{
return max(CalculateLcs(s1,p1E,s2,p2E-1),CalculateLcs(s1,p1E-1,s2,p2E));
}
}
string Lcs(string s1,int p1E,string s2,int p2E)
{
if(p1E<0||p2E<0)
return "";
if(s1[p1E]==s2[p2E])
{
return Lcs(s1,p1E-1,s2,p2E-1)+s1[p1E];
}
else
{
string str1 = Lcs(s1,p1E,s2,p2E-1);
string str2 = Lcs(s1,p1E-1,s2,p2E);
return (str1.length()>str2.length())?str1:str2;
}
}
int main()
{
string s1,s2;
cin>>s1>>s2;
//计算最长公共子序列长度
cout<<CalculateLcs(s1,s1.length()-1,s2,s2.length()-1)<<endl;
//计算最长公共子序列
cout<<Lcs(s1,s1.length()-1,s2,s2.length()-1);
return 0;
}
参考:http://blog.csdn.net/linyunzju/article/details/7747718
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: