转载:http://www.cnblogs.com/vongang/archive/2012/05/04/2483419.html

记一个KMP算法的应用,经典的KMP算法详解还是看这里

问题:给一个串,求这个串前i位构成的前缀由多少个子串组成。

比如aabaabaabaab,前2位是aa,a重复了2次,前6位是aabaab,aab重复了2次,前9位是aabaabaab,aab重复了3次,前12位是aabaabaabaab,aab重复了4次。

先说一下next()函数。pre[i] = j表示   S[1...j] = S[i - j....i];

下面讨论当i % (i - pre[i]) == 0 时,例如i = 12, pre[12] = 9:

如图。

S[1...9] == S[3...12];

因为已知 i % (i - pre[i]) == 0; 那么把i分成 i / (i - pre[i])段。

已知:

s3 == t3;

s2 == t2;

s1 == t1;

又因为t3 == s2, t1 == s1。所以 t1 = t2 = t3 = s1 = s2 = s3,也就是说 i / (i - pre[i])这几段中每一段都相等。

现在回到原问题:求这个串前i位构成的前缀由多少个子串组成,只需要找到i / (i - pre[i]) == 0的点i,则共有 i / (i - pre[i])个相同的子串构成前缀S[1...i]。

练习:POJ 1961, POJ 2406

附1961的代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <stack>
#include <cmath>
#include <algorithm> #define CL(arr, val) memset(arr, val, sizeof(arr))
#define REP(i, n) for(i = 0; i < n; ++i)
#define FOR(i, l, h) for(i = l; i <= h; ++i)
#define FORD(i, h, l) for(i = h; i >= l; --i)
#define L(x) x << 1
#define R(x) x << 1 | 1
#define MID(l, r) (l + r) >> 1
typedef long long LL; using namespace std; const int N = ; char s[N];
int pre[N];
int dp[N]; //这里加了一个数组,记录到i位置时所构成的前缀由多少个子串组成。
int n; void Next() {
int i, j = -;
pre[] = -;
for(i = ; i < n; ++i) {
while(j > - && s[j+] != s[i]) j = pre[j];
if(s[j+] == s[i]) ++j;
pre[i] = j;
}
} int main() {
freopen("data.in", "r", stdin); int i, cas = ;
while(scanf("%d", &n), n) {
scanf("%s", s);
printf("Test case #%d\n", ++cas);
Next();
REP(i, n + ) dp[i] = ;
FOR(i, , n - ) {
if((i + ) % (i - pre[i]) == && pre[i] != -) {
dp[i] = dp[pre[i]] + ; //到i的前缀就等于到pre[i]的前缀子串数加上 [pre[i], i]这个子串。
printf("%d %d\n", i + , dp[i]); //其实直接输出(i + 1)/(i - pre[i])就行,这里写搓了。。。T_T
}
}
cout << endl;
}
return ;
}

KMP算法Next()函数的一个应用的更多相关文章

  1. KMP算法-next函数求解

    KMP函数求解:一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为KMP算法.KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串 ...

  2. KMP算法的正确性证明及一个小优化

    直接把作业帖上来是不是有点不太公道呀... 无所谓啦反正各位看着开心就行 KMP算法 对于模式串$P$,建立其前缀函数$ N$ ,其中$N [q] $ 表示在$P$中,以$q$位置为结束的可以匹配到前 ...

  3. KMP算法解析(转自图灵社区)

    KMP算法是一个很精妙的字符串算法,个人认为这个算法十分符合编程美学:十分简洁,而又极难理解.笔者算法学的很烂,所以接触到这个算法的时候也是一头雾水,去网上看各种帖子,发现写着各种KMP算法详解的转载 ...

  4. 真正理解KMP算法

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4403560.html 所谓KMP算法,就是判断一个模式串是否是一个字符串的子串,通常的算法当 ...

  5. 字符串匹配算法之 kmp算法 (python版)

    字符串匹配算法之 kmp算法 (python版) 1.什么是KMP算法 KMP是三位大牛:D.E.Knuth.J.H.MorriT和V.R.Pratt同时发现的.其中第一位就是<计算机程序设计艺 ...

  6. 串匹配算法讲解 -----BF、KMP算法

      参考文章: http://www.matrix67.com/blog/archives/115     KMP算法详解 http://blog.csdn.net/yaochunnian/artic ...

  7. BZOJ 1009 HNOI2008 GT考试 KMP算法+矩阵乘法

    标题效果:给定的长度m数字字符串s.求不包括子s长度n数字串的数目 n<=10^9 看这个O(n)它与 我们不认为这 令f[i][j]长度i号码的最后的字符串j位和s前者j数字匹配方案 例如,当 ...

  8. (原创)白话KMP算法详解

    引子:BF暴力算法 KMP算法知名度相当高,燃鹅其理解难度以及代码实现对于初学数据结构和算法的同学并不友好,经过两天的总结,详细总结KMP算法如下: 初学串的模式匹配时,我们都会接触到,或者说应该能想 ...

  9. 串的模式之kmp算法实践题

    给定两个由英文字母组成的字符串 String 和 Pattern,要求找到 Pattern 在 String 中第一次出现的位置,并将此位置后的 String 的子串输出.如果找不到,则输出“Not ...

随机推荐

  1. 4.JavaSE之标识符

    标识符:Java所有的组成部分都需要名字.类名.变量名以及方法名都被称为标识符. 关键字:abstract.assert.boolean.breake.public.static.class...

  2. python实现数据结构-栈

    注:本文档主要是学习<Python核心编程(第二版)>时的练习题. 栈是一种"后进先出"的数据结构(LIFO),是一种操作受限的线性结构,数据只能从栈顶进入和栈顶出去. ...

  3. python+autoit用法

    一.自己封装的一些使用到的autoit库 import autoit class MouseControl(object): ''' AutoIt鼠标相关操作 ''' def __init__(sel ...

  4. NOI2.5 8783:单词接龙

    描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的"龙"(每个单词都最多在"龙"中 ...

  5. Catch That Cow (简单BFS+剪枝)

    Problem Description Farmer John has been informed of the location of a fugitive cow and wants to cat ...

  6. DFS(深度优先搜索遍历有向图)-03-有向图-太平洋大西洋水流问题

    给定一个 m x n 的非负整数矩阵来表示一片大陆上各个单元格的高度.“太平洋”处于大陆的左边界和上边界,而“大西洋”处于大陆的右边界和下边界. 规定水流只能按照上.下.左.右四个方向流动,且只能从高 ...

  7. Postwoman-接口测试工具

    地址是:https://postwoman.io/ ,不过只能使用它们自己提供的测试接口,如果你调试自己的API接口的话,你需要自己部署一套代码. 自己搭建一套Postwomen环境的话,只需要安装了 ...

  8. Http请求特殊符号变空格

    Http请求特殊符号变空格 今天在调试客户端向服务器传递参数时,url中的参数值出现+,空格,/,?,%,#,&等特殊符号的时候就自动变成空格,在服务器端无法获得正确的参数值.解决方法如下: ...

  9. Docker(二) 镜像

    简介 Docker镜像是什么? 它是一个只读的文件,就类似于我们安装操作系统时候所需要的那个iso光盘镜像,通过运行这个镜像来完成各种应用的部署. 这里的镜像就是一个能被docker运行起来的一个程序 ...

  10. this和static

    [this] 指的是明确的标记本类的结构 当前正在调用类中方法的对象,不是一个固定的 java中以“{}”为界限.如果现在属性名称和参数名称重名,那么默认情况下,如果没有加任何的限制,指的是最近的“{ ...