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)。然后呢我们循环地利用next,由于next的性质,即在图2中若左红串与左绿串匹配,则左红串比与右绿串匹配,因为图1的左红串与右红串是完全相等的。可以保证,每一次得出的字串都能匹配到最后一个字母,也就是得到一个前缀等于后缀。只不过这个字符串的长度在不断地减小罢了。

但是呢。。代码还是用的自己的。因为还是看不太懂别的求next数组的方法。

自己模拟了一下。我的代码应该是没有优化的。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 using namespace std;
 5
 6 int next[400005];
 7 char str[400005];
 8 int ans[400000];
 9
10 void getNext(char str[]) {
11      int len=strlen(str+1);
12      next[1] = 0;
13      for (int k=0, q=2; q<=len; ++q) {
14         while(k>0 && str[k+1] != str[q])
15         k=next[k];
16         if (str[k+1] == str[q])
17             k++;
18         next[q] = k;
19      }
20 }
21
22 int main()
23 {
24     while(scanf("%s",str+1)!= EOF)
25     {
26         int len = strlen(str+1);
27         getNext(str);
28         ans[0] = len;
29         int n = 0, i = len;
30         while(next[i]> 0)
31         {
32             n++;
33             ans[n] = next[i];
34             i = next[i];
35         }
36         for(i = n; i >= 0; i--)
37             printf("%d ", ans[i]);
38         printf("\n");
39     }
40     return 0;
41 }

时间: 2024-10-17 12:26:28

POJ 2752 KMP中next数组的理解的相关文章

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

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

[kuangbin带你飞]专题十六 KMP &amp; 扩展KMP &amp; Manacher H - Seek the Name, Seek the Fame POJ - 2752(kmp的next数组应用)

H - Seek the Name, Seek the Fame POJ - 2752 题目链接:https://vjudge.net/contest/70325#problem/H 题目: The little cat is so famous, that many couples tramp over hill and dale to Byteland, and asked the little cat to give names to their newly-born babies. Th

poj 2752 kmp(next数组的应用)

Seek the Name, Seek the Fame Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16036   Accepted: 8159 Description The little cat is so famous, that many couples tramp over hill and dale to Byteland, and asked the little cat to give names t

poj 2752 kmp的next数组

题目大意: 求一个字符串中某一个既是前缀又是后缀的前缀的结尾下标: 基本思路: 从_next[len]开始找_next[_next[len]],再找_next[_next[_next[len]]],一直找到0: 代码如下: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int inf = 0x3f3f3f3f; const int maxn = 4000

hdu 1686 &amp; poj 2406 &amp; poj 2752 (KMP入门三弹连发)

首先第一题 戳我穿越;http://acm.hdu.edu.cn/showproblem.php?pid=1686 题目大意好理解,每组输入一个子串和一个母串,问在母串中有多少个子串? 文明人不要暴力,因为宽度会超时,除去暴力后这就是赤果果的KMP KMP的重点在于在子串中建立一个匹配表,记录 到每一位的 前缀后缀 中的相同的子子串的最大长度 然后在比较子母串的时候当遇到不同时 后移的位数就是前面相同的个数减去对应的匹配表例的数 额 讲的不清不楚 那推荐戳这里:http://kb.cnblogs

POJ 2752 (KMP)

题目链接:http://poj.org/problem?id=2752 题意:给一个字符串,判断前缀和后缀是相同的位置,把这些位置从小到大输出出来. 题解:通过字符串得到next数组,然后从next[len]开始.其值就是最后一个是相同前缀后缀的位置,然后,i=next[i],就是不断的向前找,就匹配了过去. 代码如下: 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<

POJ 2752 (KMP 所有可能长度的前缀后缀) Seek the Name, Seek the Fame

题意: 求一个字符串的相同前缀后缀的所有可能的长度,这里该字符串其本身也算自己的前缀和后缀. 分析: 我们知道next数组的性质是,该字符之前的字符串的最大相同前缀后缀. 既然知道了最大的,即next[len]. 递归一次next[ next[len] ],就能求得更小的前缀. 不断的递归把所有所有可能的长度找出来,然后递归输出即可. 1 #include <cstdio> 2 #include <cstring> 3 4 const int maxn = 400000; 5 ch

POJ 2752 深刻理解KMP失配指针

思路:刚开始还在想怎么做,虽然以前是理解了失配指针的用处,但是确实不知道失配指针还有如此用处,其实还有很多用处,我用得少了不懂而已. 比如: i   0  1  2  3  4  5   6  7  8  9  10 11 p[i]  A  B R A  C  A  D  A  B  R  A  无 next[i]  0  0  0  0  1  0   1  0  1   2  3   4 next[11]=4这个肯定可以取了,因为这个后缀等于前缀嘛,然后再查询next[next[11]]=n

POJ 2752 Seek the Name, Seek the Fame KMP题解

本题是KMP的next数组的灵活运用. 具体就是看最后整个数列的最后一个字母,能有多少前缀. 理解了next数组就很容易了. #include <stdio.h> #include <string.h> #include <vector> using std::vector; const int MAX_N = 400001; char name[MAX_N]; int next[MAX_N], len; void genNext() { for (int i = 1,