KMP算法以及 next 数组求解

这几天折腾了下KMP,终于算是理解了其中的原理。现在这里大概记录下,以备不时之需!!

  

char str[MAXN];    //原串
char p[MAXN];    //需要在原串中寻找的字符串

相对于一般的字符串匹配,KMP算法优化的地方就在于   当发现当前匹配的位置 k + 1 匹配失败时,不是再回到 p 的开始位置进行匹配,而是回到 next[k] 开始匹配!

next[k] 记录了 p[0...k] 中,最长的相同前缀后缀长度 - 1 , -1 是为了转移的时候方便(数组从 0 开始)。

比如:

对于

/*
p:

| a | b | a | a | b | c | a | c |

next:

| -1| -1| 0 | 0 | 1 | -1| 0 | -1|
*/

相同前缀后缀就是前缀和后缀相同;

然后就是 next 数组的求法:

这里照搬一下算法导论中的代码,很巧妙,如果不知道原理模拟一下就清楚了。

void get_next(char *p, int *next){
    next[0] = -1;
    int k = -1;
    for(int i = 1; i < p.length; i++){
        while(k > -1 && p[k + 1] != p[i])
            k = next[k];
        if(p[k + 1] == p[i]){
            k++;
        }
        next[i] = k;
    }
}

有了 next 数组之后,在匹配字符串程序中发现不匹配的位置时,不需要将 p 的位置变量重置为 0 了,将其赋值为 next[k] 就行。

本文只是简单的描述下KMP以备忘,更详细的分析说明可以见网上大神们的博客

http://blog.csdn.net/v_july_v/article/details/7041827

时间: 2024-10-28 02:43:05

KMP算法以及 next 数组求解的相关文章

KMP算法的next[]数组通俗解释

我们在一个母字符串中查找一个子字符串有很多方法.KMP是一种最常见的改进算法,它可以在匹配过程中失配的情况下,有效地多往后面跳几个字符,加快匹配速度. 当然我们可以看到这个算法针对的是子串有对称属性,如果有对称属性,那么就需要向前查找是否有可以再次匹配的内容. 在KMP算法中有个数组,叫做前缀数组,也有的叫next数组,每一个子串有一个固定的next数组,它记录着字符串匹配过程中失配情况下可以向前多跳几个字符,当然它描述的也是子串的对称程度,程度越高,值越大,当然之前可能出现再匹配的机会就更大.

KMP算法-之next数组-详解

我们在一个母字符串中查找一个子字符串有很多方法.KMP是一种最常见的改进算法,它可以在匹配过程中失配的情况下,有效地多往后面跳几个字符,加快匹配速度. 当然我们可以看到这个算法针对的是子串有对称属性,如果有对称属性,那么就需要向前查找是否有可以再次匹配的内容. 在KMP算法中有个数组,叫做前缀数组,也有的叫next数组,每一个子串有一个固定的next数组,它记录着字符串匹配过程中失配情况下可以向前多跳几个字符,当然它描述的也是子串的对称程度,程度越高,值越大,当然之前可能出现再匹配的机会就更大.

hdu3336解读KMP算法的next数组

查看原题 题意大致是:给你一个字符串算这里面所有前缀出现的次数和.比如字符串abab,a出现2次,ab出现2次,aba出现1次,abab出现1次.总计6次. 并且结果太大,要求对1007进行模运算. AC代码 #include <iostream> using namespace std; #include <string> string s; int n,Next[200005]; void getNext() { int len = n; Next[0]=-1; int i=0

算法学习笔记 KMP算法之 next 数组详解

最近回顾了下字符串匹配 KMP 算法,相对于朴素匹配算法,KMP算法核心改进就在于:待匹配串指针 i 不发生回溯,模式串指针 j 跳转到 next[j],即变为了 j = next[j]. 由此时间复杂度由朴素匹配的 O(m*n) 降到了 O(m+n), 其中模式串长度 m, 待匹配文本串长 n. 其中,比较难理解的地方就是 next 数组的求法.next 数组的含义:代表当前字符之前的字符串中,有多大长度的相同前缀后缀,也可看作有限状态自动机的状态,而且从自动机的角度反而更容易推导一些. "前

模式匹配—KMP算法中Next值求解

#include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct { char *ch; int length; }HString; void StrAssign(HString &T,char chars[]); int get_next(HString T,int next[]); void main() { HString T; char chars[80]; int i,n,ne

KMP算法之next数组的求解思路

2.next数组的求解思路 本部分内容转自:http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html 通过上文完全可以对kmp算法的原理有个清晰的了解,那么下一步就是编程实现了,其中最重要的就是如何根据待匹配的模版字符串求出对应每一位的最大相同前后缀的长度.我先给出我的代码: 1 void makeNext(const char P[],int next[]) 2 { 3 in

字符串匹配KMP算法中Next[]数组和Nextval[]数组求法

数据结构课本上给了这么一段算法求nextval9[]数组 1 int get_nextval(SString T,int &nextval[ ]) 2 { 3 //求模式串T的next函数修正值并存入数组nextval. 4 i=1; nextval[1]=0; j=0; 5 while(i<T[0] 6 { 7 if(j==0||T[i]==T[j]) 8 { 9 ++i; 10 ++j; 11 if (T[i]!=T[j]) 12 nextval[i]=j; 13 else 14 nex

KMP算法的Next数组详解(转)

转载请注明来源,并包含相关链接. 网上有很多讲解KMP算法的博客,我就不浪费时间再写一份了.直接推荐一个当初我入门时看的博客吧: http://www.cnblogs.com/yjiyjige/p/3263858.html 这位同学用详细的图文模式讲解了KMP算法,非常适合入门. ---------------------------------------------------------------------------------------------- KMP的next数组求法是很

浅谈KMP算法及其next[]数组

KMP算法是众多优秀的模式串匹配算法中较早诞生的一个,也是相对最为人所知的一个. 算法实现简单,运行效率高,时间复杂度为O(n+m)(n和m分别为目标串和模式串的长度),比蛮力算法的O(nm)快了许多. 理解KMP算法,关键是理解其中的精髓——next[]数组. (统一起见,下文将目标字符串记作obj,将模式字符串记作pattern,这与后面的程序代码是一致的) 我们给一个字符串S定义一个next值,记作next(S),next(S)=n表示: (1)S的前n个字符构成的前缀,和后n个字符的后缀