• HDU-1238 Substrings (kmp)


    题意:求出所有串(或者其逆置串)的最长公共子串

    思路:不由的想到了 POJ-3080 Blue Jeans 这道题, 其题意是找到所有串的最长公共子串。也是暴力截取(取其中一个串)然后循环匹配(匹配时用kmp取优化)

    这里多了一个(匹配其逆置,即将所有的串均逆置存入string数组中来循环匹配即可)

    完整代码:

    //字符串长为(1~100) 总字符串个数 n (1 <= n <= 100) 
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <iostream> 
    #include <algorithm>
    using namespace std;
    const int N=500+5;
    const int M=500+5;
    
    string s[N];
    string s1[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<n;i++) s1[i].assign(s[i].rbegin(),s[i].rend());
            for(int i=n;i<2*n;i++) {
                s[i] = s1[i-n];
                
            }
            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++){
                        //匹配一次s再匹配一次逆s+n 然后再来判断最长 
                        if(!(kmp(s[k],s[k].size(),res,res.size())||kmp(s[k+n],s[k+n].size(),res,res.size()))){
                            //正序串或者逆序串都没找到匹配之后,标记 
                            flag = true;
                        } 
                    }
                    if(!flag) {
                        if(ans.size()<res.size()) ans = res;
                    }
                }
            }
            cout<<ans.size()<<endl;
        }
        return 0;
    }
  • 相关阅读:
    【原】Spark on YARN
    【原】Spark Standalone模式
    【原】日志处理-Spark
    怎样从官网下载Spring的jar包
    成功安装mysql(mysql-5.5.32-winx64.msi)后,为何服务管理器里找不到MYSQL服务名?
    SQL如何取得一个面的中心点
    Kindle2018 一周使用报告
    迅雷导致文件损坏
    苹果中国官网全面更新,官翻产品不容错过!
    如何选择windows 10 系统中默认打开程序
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11250240.html
Copyright © 2020-2023  润新知