KMP的next[]数组

KMP是众多字符串问题的基础

理解next数组尤为重要

next又称前缀数组

是 它所处位置的前一个位置的元素 与 该链 链首开始 几个元素相匹配(即相同)

举个实例来说明:

next对应的是该位置的前一个元素, 即next[i]对应a[i-1]

因为-1头指针的存在 next均对应前一个 很重要

next可以理解为指针,而它指向的位置 就是他的数值对应下标的前一个

  即 比如next[7]指向a[ next[7] - 1 ], 也就是a[2]  next[13]指向a[ next[13] - 1 ], 也就是a[5];

结合上一条, 也就是a[6]对应a[2]                           a[12]对应a[5]

这样对应的含义是: a[x]与a[y]对应,那么  从链首至a[y]的元素 均能与 a[x]及其之前 相同长度的元素匹配

举个例子 a[12]对应a[5], 也就是说 a[0]到a[5]这六个元素 能与 a[12]往前(包括a[12])共六个元素匹配  就是 a[0]到a[5] 与 a[7]到a[12] 相同

这样对应了起来有什么用呢?

这就为查找失败 往前找节约了时间。

比如, 我们在第14 这个位置查找失败了, 那么我们只需要回到next[14]这个位置也就是a[7], 看a[7]是否匹配, 若不匹配 再往前回next[7]也就是a[3]的位置

直至查找成功或者回到0

为什么呢?

因为next 数组的含义 简单的说 就是 前面有多少匹配

所以当不匹配了, 只需找到上一个匹配到哪里就可以了。

实现:

next数组的实现也是用的这个原理

 1 void getnext(int len)
 2 {
 3     int i=0, j=-1;
 4     next[0]=-1;
 5     while(i<len)
 6     {
 7         if(j==-1 || b[i]==b[j])
 8         {
 9             i++;
10             j++;
11             next[i]=j;
12         }
13         else
14             j=next[j];
15     }
16 }
 1 int kmp(int la,int lb)
 2 {
 3     int i=0, j=0;
 4     while(i<la && j<lb)
 5     {
 6         if(j==-1 || a[i]==b[j])
 7         {
 8             i++;
 9             j++;
10         }
11         else
12             j=next[j];
13     }
14     if(j>=lb)
15         return i-lb+1;
16     else
17         return -1;
18 }
时间: 2024-08-30 10:07:37

KMP的next[]数组的相关文章

String Problem hdu 3374 最小表示法加KMP的next数组

String Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1492    Accepted Submission(s): 662 Problem Description Give you a string with length N, you can generate N strings by left shifts.

poj 2406 Power Strings(kmp的nxt数组找最小循环节)

题目链接:poj 2406 Power Strings 题意: 给你一个字符串,让你找出这个字符串的最大循环次数,及最小循环节. 题解: 用kmp的nxt数组搞搞,L=j-nxt[j],为前缀j的最小循环节. 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define F(i,a,b) for(int i=(a);i<=(b);++i) 5 using namespace std;

【bzoj2384】[Ceoi2011]Match 特殊匹配条件的KMP+树状数组

题目描述 给出两个长度分别为n.m的序列A.B,求出B的所有长度为n的连续子序列(子串),满足:序列中第i小的数在序列的Ai位置. 输入 第一行包含两个整数n, m (2≤n≤m≤1000000). 第二行包含n个整数si,构成1,2,…,n的排列,1≤si≤n且si≠sj. 第三行包含m个整数hi,表示建筑的高度(1≤hi≤109,1≤i≤m),所有的hi均不相同. 每一行的整数之间用单个空格隔开. 输出 第一行包含1个整数k ,表示匹配的序列数目.第二行包含k个整数,分别为在正确匹配的每个序

HDU - 4763 Theme Section (KMP的next数组的应用)

给定一个字符串,求出一个前缀A,使得字符串的构成可以表示成ABABA的形式(B可以为空串). 输出这个前缀的最大长度. KMP算法Next数组的使用. 枚举中间的每个位置,可以根据Next数组求出这个位置对应的前缀.然后暴力判断前缀与后缀是否相等即可. 如图,枚举的位置为 i,则Next[i] = j,.然后判断0~j 是否和 k~len是否是相同的. 注意要判断合法性,即前缀 + 中缀的长度不能比当前枚举的位置大,且后缀开始的位置一定要比当前枚举的位置大. 判定完Next[i]后,一定要判定N

Match:Cyclic Nacklace(kmp的next数组的高级应用)(HDU 3746)

串珠子 题目大意:给定一个字串,要你找到如果要使之成为循环串,在末尾需要的最小的字数(只能添加字符,不能删减字符) 首先联动一下之前做过的动态规划问题POJ 3280,当然了3280这一题是用的LD,因为他可以添加或者删除(加上修改也行,但是要改状态方程了) 而我们现在要讨论的这一题(HDU 3746)是有限制的,首先它只能添加不能删除,其次一定是要在末尾添加. 其实这样的题用kmp可以很快地解决,其实这样的题目是循环节的题目,之前我已经写过很多了,这一题是对循环节的深刻理解. 首先我们我们明白

POJ 2752 KMP中next数组的理解

感觉这里讲的挺好的.http://cavenkaka.iteye.com/blog/1569062 就是不断递归next数组.长度不断减小. 题意:给你一个串,如果这个串存在一个长度为n的前缀串,和长度为n的后缀串,并且这两个串相等,则输出他们的长度n.求出所有的长度n. 思路:KMP中的get_next().对前缀函数next[]又有了进一步的理解,str[1]~~str[next[len]]中的内容一定能与str[1+len-next[len]]~~str[len]匹配(图1).然后呢我们循

KMP算法&amp;next数组总结

http://www.cnblogs.com/yjiyjige/p/3263858.html KMP算法应该是每一本<数据结构>书都会讲的,算是知名度最高的算法之一了,但很可惜,我大二那年压根就没看懂过~~~ 之后也在很多地方也都经常看到讲解KMP算法的文章,看久了好像也知道是怎么一回事,但总感觉有些地方自己还是没有完全懂明白.这两天花了点时间总结一下,有点小体会,我希望可以通过我自己的语言来把这个算法的一些细节梳理清楚,也算是考验一下自己有真正理解这个算法. 什么是KMP算法: KMP是三位

POJ 2752+KMP+利用next数组性质求出所有相同的前缀和后缀

题目链接:点击进入 这个题目要求所有相同的前缀和后缀的长度.我们可以利用KMP算法中next数组的性质,在next[len]这个点不断的失配下去,这样就可以将所有相同的前后缀的长度求出来.还要注意这个中整个串的长度也可以看成是一个合法的解. 代码如下: #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=400000+100; char str

【POJ 3167】Cow Patterns (KMP+树状数组)

Cow Patterns Description A particular subgroup of K (1 <= K <= 25,000) of Farmer John's cows likes to make trouble. When placed in a line, these troublemakers stand together in a particular order. In order to locate these troublemakers, FJ has lined