问题 G: 最长公共子串问题

 

希腊有一个著名的历史学家,他为了专心写一本史学巨著,而把自己关在一个高塔之上。有一天,他目睹了一场凶杀案的发生,但事后,他惊讶地发现所有围观人的证词都不一样,甚至有的完全相反。于是,他放弃了继续写作的念头。他说:“人们连发生在眼前的事实都分辨不清,我又怎么知道我写的历史是真是假呢?”

虽然历史的真假我们很难辨别,但文章是否抄袭,我们还是可以用所谓的LCS算法解决的。

给出两个字符串S1和S2,我们现在希望了解两个字符串之间的“相似度”。这个相似度是这样定义的:找出第三个字符串S3,组成S3的元素也出现在S1和S2中,而且这些元素必须是以相同的顺序出现,但不必要是连续的。能找到的S3越长则S1和S2就越相似。相似度即是这个S3的长度。例如,当S1="abcde",S2="dabfda",S3就是"abd", S1和S2的相似度就是3。

输入

第一行为一个整数,表示第一个字符串的长度。

第二行为第一个字符串。

第三行为一个整数,表示第二个字符串的长度。

第二行为第二个字符串。

输出

一个整数,即两个字符串的相似度。

样例输入 Copy

5
abccb
5
acabc

样例输出 Copy

3
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map> 
#include<bits/stdc++.h> 
using namespace std;
typedef long long ll; 
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int INF=0x3f3f3f3f;
const int maxn=5e3;
int n,m;
string str1,str2;
int dp[maxn][maxn];
void inint(){
    cin>>n;
    cin>>str1;
    cin>>m;
    cin>>str2; 
}
int main(){
    inint();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(str1[i-1]==str2[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",dp[n][m]); 
}

 输出方案:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map> 
#include<bits/stdc++.h> 
using namespace std;
typedef long long ll; 
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int INF=0x3f3f3f3f;
const int maxn=5e3;
int n,m;
string str1,str2;
int dp[maxn][maxn];
char ans[maxn];
void inint(){
    cin>>n;
    cin>>str1;
    cin>>m;
    cin>>str2; 
}
int main(){
    inint();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(str1[i-1]==str2[j-1]){
                dp[i][j]=dp[i-1][j-1]+1;
            }
            else{
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cout<<dp[i][j]<<" ";
        }
        cout<<endl;
    }
    int l=n,r=m;
    int p=0;
    while(l>0&&r>0){
        if(str1[l-1]==str2[r-1]){
            ans[p++]=str1[l-1];
            l--;
            r--;
        }
        else if(dp[l][r-1]>dp[l-1][r]){
            r--;
        }
        else{
            l--;
        }
    }
    cout<<endl;
    printf("%d\n",dp[n][m]); 
    for(int i=p-1;i>=0;i--){
        cout<<ans[i];
    }
}
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map> 
#include<bits/stdc++.h> 
using namespace std;
typedef long long ll; 
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int INF=0x3f3f3f3f;
const int maxn=5e3;
int n,m;
string str1,str2;
int dp[maxn][maxn];
char ans[maxn];
void inint(){
    cin>>n;
    cin>>str1;
    cin>>m;
    cin>>str2; 
}
int main(){
    inint();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(str1[i-1]==str2[j-1]){
                dp[i][j]=dp[i-1][j-1]+1;
            }
            else{
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cout<<dp[i][j]<<" ";
        }
        cout<<endl;
    }
    int l=n,r=m;
    int p=0;
    while(l>0&&r>0){
        if(str1[l-1]==str2[r-1]){
            ans[p++]=str1[l-1];
            l--;
            r--;
        }
        else if(dp[l][r-1]>dp[l-1][r]){
            r--;
        }
        else{
            l--;
        }
    }
    cout<<endl;
    printf("%d\n",dp[n][m]); 
    for(int i=p-1;i>=0;i--){
        cout<<ans[i];
    }
}

 

posted @ 2021-07-03 11:37  lipu123  阅读(68)  评论(0编辑  收藏  举报