zoukankan      html  css  js  c++  java
  • HDOJ(1238) KMP

    Substrings

    http://acm.hdu.edu.cn/showproblem.php?pid=1238

    先找到长度最短的字符串,把它的子串和该子串的逆序(按长度从大到小)依次与其他字符串匹配。

    如果某个子串或它的逆序(如:“ro” ,”or“)和其他字符串都匹配,就返回此时的长度。

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<vector>
    #include<algorithm>
    using namespace std;
    
    //下标以0开始的KMP
    void get_next(string b, int *next)
    {
        int i=0;
        int j=-1;
        next[i]=-1;
        int len_b=b.size();
        while(i<len_b-1)
        {
            if(j==-1||b[i]==b[j])
            {
                ++i;
                ++j;
                if(b[i]!=b[j])
                    next[i]=j;
                else
                    next[i]=next[j];
            }
            else
            {
                j = next[j];
            }
        }
    }
    
    int KMP(string a,string b)
    {
        int i=0;
        int j=0;
        int len_a=a.size();
        int len_b=b.size();
        int next[101];
        get_next(b,next);
        while(i<len_a&&j<len_b)
        {
            if(j==-1||a[i]==b[j])
            {
                ++i;
                ++j;
            }
            else
            {
                j=next[j];
            }
        }
        if(j>=len_b)
            return 1;
        else
            return 0;
    }
    
    int solve(vector<string> str,int mini)
    {
        string sub1,sub2;
        int i,j,k,m,res=0;
        int len=str[mini].size();
        for(i=len;i>=1;i--)
        {
            for(j=0;i+j<=len;j++)
            {
                sub1=str[mini].substr(j,i);  //选取str[mini]中以j开头长度为i的字串
                sub2=sub1;
                reverse(sub2.begin(),sub2.end());//逆置字符串
                int l=str.size();
                for(k=0;k<l;k++)
                {
                    string s=str[k];
                    if(KMP(s,sub1)==0&&KMP(s,sub2)==0)
                    {
                        break;
                    }
                }
                if(k>=l)
                {
                    
                    res=i;
                    goto A;
                }
            }
        }
        A: return res;
    }
    int main()
    {
        int t,n,i,mini;
        vector<string> str;
        string s;
        scanf("%d",&t);
        while(t--)
        {
            str.clear();
            scanf("%d",&n);
            for(i=0;i<n;i++)
            {
                cin>>s;
                str.push_back(s);
            }
            mini=0;
            int len=str.size();
            for(i=1;i<len;i++)
            {
                if(str[i].size()<str[mini].size())
                {
                    mini=i;
                }
            }
            printf("%d
    ",solve(str,mini));
        }
        return 0;
    }
    View Code

    KMP模板

    下标以0开始

    void get_next(string b, int *next)
    {
        int i=0;
        int j=-1;
        next[i]=-1;
        int len_b=b.size();
        while(i<len_b-1)
        {
            if(j==-1||b[i]==b[j])
            {
                ++i;
                ++j;
                if(b[i]!=b[j])
                    next[i]=j;
                else
                    next[i]=next[j];
            }
            else
            {
                j = next[j];
            }
        }
    }
    
    int KMP(string a,string b)
    {
        int i=0;
        int j=0;
        int len_a=a.size();
        int len_b=b.size();
        int next[101];
        get_next(b,next);
        while(i<len_a&&j<len_b)
        {
            if(j==-1||a[i]==b[j])
            {
                ++i;
                ++j;
            }
            else
            {
                j=next[j];
            }
        }
        if(j>=len_b)
            return i-len_b;
        else
            return 0;
    }
    View Code

    下标从1开始

    void get_next(char *b,int *next)
    {
        int i=1;
        int j=0; 
        next[1]= 0; 
        int len_b=strlen(b)-1;     //下标从1开始,子串的长度=strlen(b)-1
        while(i<len_b) 
        { 
            if(j==0||b[i]==b[j])   //b[i]表示后缀的单个字符
            {                      //b[j]表示前缀的单个字符
                ++i; 
                ++j; 
                if (b[i]!=b[j]) 
                    next[i]=j; 
                else 
                    next[i]=next[j]; 
            }  
            else   
                j=next[j];        //若字符不相同,则j值回溯
        } 
    }
    int KMP(char *a,char *b,int pos)
    {
        int i=pos;               //i用于主串a当前位置下标值
                                 //若pos不为1,则从pos开始
        int j=1;                 //j用于字串b当前位置下标值
        int len_a=strlen(a)-1; 
        int len_b=strlen(b)-1;
        int next[101];
         get_next(b,next);        //对字串b分析,得到next数组
        while(i<=len_a&&j<=len_b)
        {
            if(j==0||a[i]==b[j])
            {
                ++i;
                ++j;
            }
            else
            {
                j=next[j];
            }
        }
        if(j>len_b)
            return i-len_b;   
        else
            return 0;
    }
    View Code

    下标以1开始的next数组,实际上,是下标以0开始的next数组的值+1。KMP算法最重要的是得到子串的next[]。

  • 相关阅读:
    devops之 gitlab-ci + mesos + docker + marathon 持续发布③marathon常用api的使用
    centos7环境下二进制编译安装ffmpeg
    jenkins2.236 + sonarqube7.6 + sonar-scanner3.3的集成配置和生产环境使用示例
    zabbix添加top10内存和cpu资源占用情况
    Marathon基于有认证的harbor仓库创建应用
    devops之 gitlab-ci + mesos + docker + marathon 持续发布③marathon 结合 gitlab-ci的CICD持续发布
    docker拉取指定版本的centos和python镜像
    devops之 gitlab-ci + mesos + docker + marathon 持续发布②安装marathon
    devops之 gitlab-ci + mesos + docker + marathon 持续发布①mesos集群环境的搭建
    zabbix4.0监控gpu
  • 原文地址:https://www.cnblogs.com/chiry/p/3269707.html
Copyright © 2011-2022 走看看