KMP算法

http://blog.csdn.net/ebowtang/article/details/49129363

http://www.tuicool.com/articles/e2Qbyyf

http://billhoo.blog.51cto.com/2337751/411486/

很详细,感谢三位博主。

class KMP
{
public:
    void MakeNext(string p, vector<int> &next);
    string::size_type match(const string &t, const string &p, vector<int> &next);
};
inline
void KMP::MakeNext(string p, vector<int> &next){//next容器中存储的对应串的最大对称程度
    auto m = p.size();          //p字符串长度
    next[0] = 0;                //开头的字符肯定是0                         
    int k = 0;                  //k是最大对称长度
    for (string::size_type q = 1; q != m; ++q){
        while (k>0&&p[q] != p[k]){ //当k=0时,跳出循环直接比较p[q]==p[0]是否相等  
            k = next[k - 1];   //判断是否存在更小的对称性
            //  0 1 2 3 4 5 6 7 8 9 10 11
            //p:a b c c a b c c a b c a
            //k:0 0 0 0 1 2 3 4 5 6 7
            // p[11]=a 不等于 p[7]=c  所以大的对称性没有继续了 abccabc  
            // next[6]就的值就是这个小串(abccabc)的最大对称程度
            //k=3  那么看p[11]=a 和尾部的其他三个字符有没有和小串开头四个构成对称
            //以此类推
        }
        if (p[q] == p[k])
            ++k;
        next[q] = k;
    }
}
inline
string::size_type KMP::match(const string &t, const string &p, vector<int> &next){
    auto nt = t.size();
    auto np = p.size();
    MakeNext(p, next);//生成next表
    for (string::size_type i = 0, q = 0; i != nt; ++i){
        while (q>0&&p[q] != t[i]){
            q = next[q - 1];

        }
        if (p[q] == t[i])      //如果配对 那就后移一位继续与T(T的i通过for也在后移)比较
            ++q;
        if (q == np){            //如果全部匹配了
            q = next[q - 1];   //ABCABAD
                               //   ABA   这时候全匹配了 但往后移动一位,因为next[2]=1 有对称存在
            return i - np + 1;//返回匹配的第一个位置 和s.find(str1)统一
        }
    }
}
实现代码

 

posted on 2016-12-15 16:23  ToBeAprogrammer  阅读(131)  评论(0)    收藏  举报

导航