您的位置:首页 > 产品设计 > UI/UE

POJ 2264 Advanced Fruits(最长公共子序列)

2015-01-08 22:54 162 查看
这题要用到最长公共子序列,又是DP,可是不会,于是就去学这个,看了一会儿,终于有点心得了。

主体思想就是先求出最长公共子序列,然后把公共字符之前的所有字符都合并起来。具体请看下面的注释。

#include<cstdio>
#include<cstring>
const int N=105;
char s1
,s2
,s[N*2];
int lcs

,index1
,index2
;//index和index2是用来记录公共字符所在的索引。
void get_lcs()
{
int len1=strlen(s1);
int len2=strlen(s2);
memset(lcs,0,sizeof(lcs));
for(int i=1;i<=len1;i++)//求出最长公共子序列的长度
{
for(int j=1;j<=len2;j++)
{
if(s1[i-1]==s2[j-1])
lcs[i][j]=lcs[i-1][j-1]+1;
else
{
if(lcs[i-1][j]>lcs[i][j-1])
lcs[i][j]=lcs[i-1][j];
else
lcs[i][j]=lcs[i][j-1];
}
}
}
int i=len1-1,j=len2-1,top=0;
while(i!=-1&&j!=-1)//求出所有公共字符的索引
{
if(s1[i]==s2[j])
{
index1[top]=i,index2[top]=j;
top++,i--,j--;
}
else
{
if(lcs[i+1][j+1]==lcs[i][j])
i--,j--;
else
{
if(lcs[i+1][j]>lcs[i][j+1])
j--;
else
i--;
}
}
}
index1[top]=-1,index2[top]=-1;//设置这个是为了合并第一个公共字符之前的字符
//for(int i=0;i<=top;i++)
//printf("%d,index1=%d,index2=%d\n",i,index1[i],index2[i]);
int s_top=0;
for(int i=top;i>=1;i--)
{
for(int j=index1[i]+1;j<index1[i-1];j++)//两个公共字符之间的字符都要合并
s[s_top++]=s1[j];
for(int j=index2[i]+1;j<index2[i-1];j++)
s[s_top++]=s2[j];
s[s_top++]=s1[index1[i-1]];
}
for(int j=index1[0]+1;j<len1;j++)//最后一个公共字符之后剩下的字符合并
s[s_top++]=s1[j];
for(int j=index2[0]+1;j<len2;j++)
s[s_top++]=s2[j];
}
int main()
{
while(scanf("%s%s",s1,s2)!=EOF)
{
for(int i=0;i<2*N;i++)
s[i]='\0';
get_lcs();
printf("%s\n",s);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: