码迷,mamicode.com
首页 > 编程语言 > 详细

KMP算法

时间:2017-05-28 16:08:33      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:print   是什么   pac   ++i   接下来   网上   turn   bcd   div   

这个算法太狗血,弄了好几天才明白一点,而且网上不同的博客写的方法不相同,表示很无奈啊。。。

接下来我要讲一讲我理解的KMP,我理解的有点浅,主要给几个事例,就不模拟计算过程了,具体KMP是什么,或者想要知道大致模拟过程的,自行百度。

先粘上代码

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
int next[10000];
void prekmp(char x[], int m) {//这一步坑爹,next数组为一张部分匹配表
    int i = 0, j = -1;
     next[0] = -1;
     while(i < m) {
         while(j != -1  && x[i] != x[j] ) j = next[j];
         if(x[++i] == x[++j]) next[i] = next[j];
         else next[i] = j;
     }
}
int KMP(char x[], int m, char y[], int n) {这个还好理解
    int i = 0, j = 0;
    int ans = 0;
    prekmp(x, m);
    while(i < n) {
        while(j != -1 && x[j] != y[i]) j = next[j];//用到next数组,不用一个一个对比,直接用放在next的位置,位置文章最后有解释
         i++; j++;
        if(j >= m) {
            ans++;
            j = next[j];
        }
    }
    return ans;
}
int main() {
    //freopen("in.txt","r",stdin);
    //freopen("out.txt,"w",stdout");
    ios_base::sync_with_stdio(0);cin.tie();
     char x[10000], y[10000];
     scanf("%s%s",y,x);
     int m = strlen(x); 
     int n = strlen(y);
     cout << endl;
     cout << KMP(x, m, y, n) << endl;
     for(int i = 0; i < m; i++)//print value
         cout << next[i] << "" ;
     cout << endl;
     return 0;
}

 

 

 

next数组的事例

位置都是从0开始

abc            -1 0 0

abca          -1 0 0 -1  如果字母跟首字母相同,就为-1

abcabe        -1 0 0 -1 0 2  e字母和c字母不相同,所以e字母指向c的位置

abcdabead       -1 0 0 0 -1 0 2 -1 1  第三个a同第三个a之前字符串的比较,最后一个字母d指向第二个字母b的位置

abcabcabde        -1 0 0 -1 0 0 -1 0 5 0  第三个a之前有连续重复的,第三个指向第6个字母的位置  

abcabdabea        -1 0 0 -1 0 2 -1 0 2 -1  第三个a之前的不连续,所以指向第三个字母的位置

KMP算法

标签:print   是什么   pac   ++i   接下来   网上   turn   bcd   div   

原文地址:http://www.cnblogs.com/creativepower/p/6915768.html

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