動態規劃解決 最長公共子序列 與 最長公共字串問題

一、最長公共子序列

#include<bits/stdc++.h>
#include<string>
#include<cstdio>
#include<iostream>
using namespace std;
string solve(string s1,string s2){
    s1="*"+s1;
    s2="&"+s2;
    int n1=s1.size(),n2=s2.size();
    int dp[n1+1][n2+1];
    memset(dp,0,sizeof(dp));
    string ans="";
    for(int i=1;i<n1;i++){
        for(int j=1;j<n2;j++){
            if(s1[i]==s2[j]){
                dp[i][j]=dp[i-1][j-1]+1;
            }
            else
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
        }
    }
    n1-=1,n2-=1;
    while(n1>=0&&n2>=0){
        if(s1[n1]==s2[n2]){
            ans+=s1[n1];
            n1--;
            n2--;
        }
        else if(dp[n1-1][n2]>dp[n1][n2-1])
            n1-=1;
        else
            n2-=1;
    }
    reverse(ans.begin(),ans.end());
    return ans;
}
int main()
{
    string s1="12345EF",s2="1AB2345CD";
    cout<<solve(s1,s2)<<endl;
    return 0;
}

最後dp[n1-1][n2-1]就是最長公共子序列的長度 

二:最長公共子串

最後maxx就是最長公共子串的長度,求出最長公共字串的長度之後,關鍵是怎麼返回去找到任意一個最長的子串,可以遍歷找到dp數組的最大值,一直往左上角走就是答案。

#include<bits/stdc++.h>
#include<string>
#include<cstdio>
#include<iostream>
using namespace std;
string solve(string s1,string s2){
    s1="*"+s1;
    s2="&"+s2;
    int n1=s1.size(),n2=s2.size();
    int dp[n1+1][n2+1];
    memset(dp,0,sizeof(dp));
    string ans="";
    int maxx=-1,p=0,q=0;
    for(int i=1;i<n1;i++){
        for(int j=1;j<n2;j++){
            if(s1[i]==s2[j]){
                dp[i][j]=dp[i-1][j-1]+1;
            }
            else
                dp[i][j]=0;
            if(dp[i][j]>=maxx){
                maxx=dp[i][j];
                p=i;
                q=j;
            }
        }
    }
   // cout<<p<<" "<<q<<endl;
    while(p>=0&&q>=0){
        if(s1[p]==s2[q]){
            ans+=s1[p];
            p--;
            q--;
        }
        else
            break;
    }
    reverse(ans.begin(),ans.end());
    return ans;
}
int main()
{
    string s1="12345EF",s2="1AB2345CD";
    cout<<solve(s1,s2)<<endl;
    return 0;
}

最長公共子串就是最近遇到的一個面試題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章