POJ-3080 Blue Jeans (暴力kmp)

题意:找出所给的多个串的相同子串部分

思路:暴力遍历(截取) 其中一个串的部分,然后将其用kmp简化与其他串的匹配 ,用ans来存储最终的答案,如果答案有多个则用 min()来取最小字典序

完整代码:


#include <cstdio>
#include <cstring>
#include <string>
#include <iostream> 
#include <algorithm>
using namespace std;
const int N=10+5;
const int M=60+5;

string s[N];
int nex[M];

void getnext(string str,int len){
    int i=0,j=-1;
    nex[0]=-1;
    while(i<len){
        if(j==-1||str[i]==str[j])
            nex[++i]=++j;
        else j=nex[j];
    }
}
bool kmp(string s1,int len1,string s2,int len2){
    int i=0,j=0;
    while(i<len1){
        if(j==-1||s1[i]==s2[j])
            ++i,++j;
        else j=nex[j];
        if(j==len2)return true;
    }
    return false;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);   
    int T,n;
    cin>>T;
    while(T--){
        cin>>n;
        for(int i=0;i<n;i++)cin>>s[i];
        string ans="";
        for(int i=0;i<s[0].size();i++) //起点
        {
            for(int j=1;i+j<=s[0].size();j++) //长度
            {
                string res=s[0].substr(i,j);
                getnext(res,res.size());
                bool flag = false;
                for(int k=1;k<n;k++)
                    if(!kmp(s[k],s[k].size(),res,res.size()))
                        flag= true;
                if(!flag)
                {
                    if(ans.size()<res.size()) ans=res;  //优先长度更长的公共子串
                    else if(ans.size()==res.size()) ans=min(ans,res); //长度相同,按字典序排序
                }
            }
        }
        if(ans.size()<3)cout<<"no significant commonalities"<<endl;
        else cout<<ans<<endl;
    }
    return 0;
}
 
原文地址:https://www.cnblogs.com/Tianwell/p/11214465.html