zoukankan      html  css  js  c++  java
  • KMP算法代码

    以下是本人根据上一篇博客随笔http://www.cnblogs.com/jiayouwyhit/p/3251832.html,所写的KMP算法代码(暂未优化),个人认为在基于上一篇博客的基础上,代码的思路是相对很清晰的。以后的KMP算法求解建议依照此版本进行代码构思。再次强调下本版本的next数组:

    例如:

    //    T = a b c a b c a b c d
    //下标:  0 1 2 3 4 5 6 7 8 9
    //next:  -1 0 0 0 1 2 3 4 5 6
    该版本的next数组的一个好处在于:字符串的下标是从零开始的,符合C++下string本身的特点;且另next[0]=-1,取值非常巧妙。
    //新的KMP算法思路
    int myNewKMP(const string& P,const string& T,const int* next)
    {
        int P_length = P.size(),T_length = T.size();
        int i=0,q=0;//i----主串下标;q---子串下标号
    
        while (i<P_length && q<T_length)
        {
            if(q==-1 || P[i]==T[q])
            {
                ++i;
                ++q;
            }
            else{
                q=next[q];
            }
        }
        if(q==T_length)
            return (i-T_length);
        else
            return -1;
    }
    
    //新的求next数组的思路
    //next 数组举例示范:
    //    T = a b c a b c a b c d
    //下标:   0 1 2 3 4 5 6 7 8 9
    //next:  -1 0 0 0 1 2 3 4 5 6 
    void myNewNext(const string & T, int *next)
    {
        int T_length=T.size();
        int k=0,q=1;//k---前缀;q----后缀
        next[0]=-1;
        while (q<T_length)
        {
            if(k==-1 ||T[q]==T[k])//K==-1说明K=0了,T[k]!=T[q],故需将q往后移动,而K(也就是next[q])取值为0.
            {
                ++q;
                ++k;
                next[q]=k;
            }
            else
                k = next[k];
        }
    }

    
    
    //优化后的
    void myNewNextUpdate(const string & T, int *next)
    {
    int T_length=T.size();
    int k=0,q=1;//k---前缀;q----后缀
    next[0]=-1;
    while (q<T_length)
    {
    if(k==-1 ||T[q]==T[k])//K==-1说明K=0了,T[k]!=T[q],故需将q往后移动,而K(也就是next[q])取值为0.
    {
    ++q;
    ++k;
    //注意:注意这里是++i和++j之后的p[i]、p[j]
    //修改:因为如果T[q]==T[k],则假如主串中某个字符与T[q]没有匹配上时,则把该字符与T[k]匹配将仍然是匹配不上的。
    if(T[q]!=T[k])
    next[q]=k;
    else
    next[q]=next[k];
    }
    else
    k = next[k];
    }
    }
    
    
    
    int main()
    {
        int i;
        int shift = -1;
        int next[20]={0};
        string P= "ababxbaaaabaaacfdsss";
        string T = "aaabaaac";
        cout<<"P="<<P<<endl;
        cout<<"T="<<T<<endl;
    
        myNewNext(T,next);
        if((shift = myNewKMP(P,T,next)) !=-1)
            cout<<"shift is "<<shift<<endl;
        for (i = 0; i< T.size(); ++i)
        {
            printf("%d ",next[i]);
        }
        printf("
    ");
    
        return 0;
    }


  • 相关阅读:
    七月在线爬虫班学习笔记(五)——scrapy spider的几种爬取方式
    七月在线爬虫班学习笔记(四)——相关库使用与登录问题
    七月在线爬虫班学习笔记(三)——爬虫基础知识与简易爬虫实现
    文件处理工具类
    执行脚本工具类
    LRU
    springboot 整合 memcached
    转载连接
    SpringBoot2.x中redis使用(lettuce)
    Redis 数据类型
  • 原文地址:https://www.cnblogs.com/jiayouwyhit/p/3251951.html
Copyright © 2011-2022 走看看