输出最长公共子序列

试题描述

    还是公共子序列,如果不知道什么叫公共子序列,请先阅读第0071题。本题给定两个字符串 str1 和 str2 ,请编写程序求出这两个字符串最长的公共子串。如果最大长度的公共子串有多个,输出字典序最小的那一个。

输入
两行,每行一个只含英文字母的字符串
输出
一个字符串
输入示例
ABCDDDBAMN BCDABM
输出示例
BCDAM
其他说明
输入的字符串长度均不会超过1000。

 

#include<cstdio>
#include<cctype>
#include<algorithm>
#include<cstring>
#define maxn 1005
using namespace std;
inline int read()
{
    int x=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-')f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
int lasta[maxn][27],lastb[maxn][27]; 
int f[maxn][maxn],ans[maxn],cnt;
char a[maxn],b[maxn];
bool flag;
void dfs(int res,int n,int m)
{
 if(flag) return;
 if(res==0)
    {
 flag=1;
 for(int i=0;i<cnt;i++)
 printf("%c",ans[i]+'A');
 printf("\n");
 return;
 }
 for(int i=0;i<26;i++)
 {
 int posa=lasta[n][i],posb=lastb[m][i];
 if(f[posa+1][posb+1]==res)
 {
 ans[cnt++]=i;
 dfs(res-1,posa-1,posb-1);
 cnt--;
 }
 }
}
int main()
{
    scanf("%s%s",a,b);
    int n=strlen(a),m=strlen(b);
    for(int i=0;i<n/2;i++)swap(a[i],a[n-i-1]);
 for(int i=0;i<m/2;i++)swap(b[i],b[m-i-1]); 
 for(int i=1;i<=n;i++)
 for(int j=1;j<=m;j++)
 if(a[i-1]==b[j-1])
 f[i][j]=f[i-1][j-1]+1;
 else f[i][j]=max(f[i-1][j],f[i][j-1]);

 memset(lasta,-1,sizeof(lasta));
 memset(lastb,-1,sizeof(lastb));
 for(int i=0;i<n;i++)
 {
 for(int j=i;j>=0;j--)
if(lasta[i][a[j]-'A']==-1)
 lasta[i][a[j]-'A']=j;
 }
    for(int i=0;i<m;i++)
 {
 for(int j=i;j>=0;j--)
if(lastb[i][b[j]-'A']==-1)
 lastb[i][b[j]-'A']=j;
 }
 dfs(f[n][m],n-1,m-1);
    return 0;
} 
View Code

 

转载于:https://www.cnblogs.com/jason2003/p/6590583.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值