码迷,mamicode.com
首页 > 其他好文 > 详细

KMP代码及思路解析

时间:2015-04-13 09:39:22      阅读:114      评论:0      收藏:0      [点我收藏+]

标签:算法   搜索   kmp   


首先推荐这篇KMP思想的介绍:字符串匹配的KMP算法


KMP代码的关键是:

1、得到搜索串每个字符的匹配值

2、当字符匹配失败时的转移

(搜索串指搜索目标串。)


1:

第一个循环:遍历每个字符,表示搜索的是 该字符及之前所有字符组成的串。

第二个循环:遍历所有长度的子串。

第三个循环:比较子串是否相同。

搜索的目标是:所有相同的子串中最长字串的长度。所以维护一个maxl变量。

(在此“子串”指前缀和后缀。)

(代码中未清零model数组。)

2:

匹配失败时的转移就很简单了。

若当前字符匹配失败,前一字符的model值就是前面已匹配串的前缀与后缀相同的个数,直接令搜索串的偏移等于该数值就行。(代码不同由于数组脚标可能会有+-1差别。)



void inis(string t, int* model){
    //初始化得到搜索串的模式
    //第一个循环 i为字符串尾
    for(int i=1; i<=t.size(); i++){
        //第二个循环 k为字串长度
        for(int k=1; k<i; k++){
            //cout<<"k:"<<k<<endl;
            int maxl = 0;//最长匹配子串的长
            bool ok = true;
            //第三个循环 h为子串比较的位
            for(int h=0; h<k; h++){
                //cout<<"h:"<<h<<"--"<<t[h]<<" "<<t[i-k+h]<<endl;
                if(t[h] == t[i-k+h]){
                    maxl++;
                }else{
                    ok = false;
                    break;
                }
               // cout<<h<<"-"<<len-k+h<<endl;
            }
            if(ok && maxl>model[i-1]){
                model[i-1] = maxl;
            }
        }
    }
}
int sf(string s, string t, int* model, int off){
    //从偏移off处开始搜索 返回目标串首字符从0开始的索引
    int slen = s.size();
    int tlen = t.size();
    int i=off, k=0;
    for( ; i<slen; i++){
        //cout<<"i:"<<i<<endl;
        //cout<<s[i]<<"  "<<t[k]<<endl;
        if(s[i] == t[k]){
            //cout<<"k++  "<<k<<endl;
            k++;
        }else{
            //状态转移
            if(k != 0){
                k = model[k-1];
                i--;
            }
        }
        if(k == tlen){
            return i - k + 1;//首
            //return i;//尾字母
        }
    }
    return -1;
}


KMP代码及思路解析

标签:算法   搜索   kmp   

原文地址:http://blog.csdn.net/windroid/article/details/45013851

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!