zoukankan      html  css  js  c++  java
  • POJ 3450 Corporate Identity (KMP,求公共子串,方法很妙)

    http://blog.sina.com.cn/s/blog_74e20d8901010pwp.html
    我采用的是方法三。

    注意:当长度相同时,取字典序最小的。

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    /*
    http://blog.sina.com.cn/s/blog_74e20d8901010pwp.html
    我采用的是方法三。
    
    注意:当长度相同时,取字典序最小的。
    */
    using namespace std;
    const int maxn=4005;
    char str[maxn][210];
    int n;
    int minlen; //n个字符串中最短的长度
    int id; //长度最短字符串的编号
    int next[210];
    
    void getNext(char*P){
        int k;
        int lm=strlen(P);
        next[1]=0;
        k=0;
        for(int i=1;i<lm;i++){
            while(k>0 && P[k]!=P[i])
                k=next[k];
            if(P[k]==P[i])
                k++;
            next[i+1]=k;
        }
    }
    
    int kmp(char*T,char*P){
        int k,c;
        c=0; //表示字符串P在T中能够匹配的最大长度
        int ln=strlen(T),lm=strlen(P);
        for(int i=0;i<ln;i++){
            while(k>0&&P[k]!=T[i])
                k=next[k];
            if(P[k]==T[i])
                k++;
            if(k>c)
                c=k;
            if(k==lm)
                return k;
        }
        return c;
    }
    int main()
    {
        int l;
        while(scanf("%d",&n)!=EOF){
            if(n==0)
                break;
            minlen=1000;
            for(int i=1;i<=n;i++){
                scanf("%s",str[i]);
                l=strlen(str[i]);
                if(l<minlen){
                    minlen=l;
                    id=i;
                }
            }
            char tmp[210],s[210];
            int minl,maxl=0,cnt;
            //minl为枚举的后缀在其余n-1个字符串中都能匹配的长度
            //maxl为公共子串的最大长度
            char ans[210]; //所求公共子串
            for(int i=1;i<=minlen;i++){
                strncpy(tmp,str[id]+minlen-i,i);
                tmp[i]='';
                getNext(tmp);
                minl=i+1;
                for(int j=1;j<=n;j++){
                    if(j!=id){
                        cnt=kmp(str[j],tmp);
                        minl=min(cnt,minl);
                    }
                }
                if(minl>maxl){
                    maxl=minl;
                    strncpy(ans,tmp,minl);
                    ans[minl]='';
                }
                //如果相等长度,则输出字典序最小的
                else if(minl==maxl){
                    strncpy(s,tmp,minl);
                    s[minl]='';
                    if(strcmp(s,ans)<0)
                        strcpy(ans,s);
                }
            }
            if(maxl==0)
                printf("IDENTITY LOST
    ");
            else
                printf("%s
    ",ans);
    
        }
        return 0;
    }
    View Code
  • 相关阅读:
    .Net 控制台动态刷新使用
    VS 将!=转换成 ≠
    C# 自定义Html分页
    .NET MVC ModelBinder基本使用
    C# 重启电脑 程序自启动
    ASP.NET JsonResult返回日期格式及首字母大写解决
    java快速排序代码实现
    系统高可靠的设计需要考虑哪些方面
    sentinel源码学习--transport模块
    TiDB学习笔记分享--存储篇
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/3546642.html
Copyright © 2011-2022 走看看