KMP算法Next()函数的一个应用
转载: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]。
附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()函数的一个应用的更多相关文章
- KMP算法-next函数求解
KMP函数求解:一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为KMP算法.KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串 ...
- KMP算法的正确性证明及一个小优化
直接把作业帖上来是不是有点不太公道呀... 无所谓啦反正各位看着开心就行 KMP算法 对于模式串$P$,建立其前缀函数$ N$ ,其中$N [q] $ 表示在$P$中,以$q$位置为结束的可以匹配到前 ...
- KMP算法解析(转自图灵社区)
KMP算法是一个很精妙的字符串算法,个人认为这个算法十分符合编程美学:十分简洁,而又极难理解.笔者算法学的很烂,所以接触到这个算法的时候也是一头雾水,去网上看各种帖子,发现写着各种KMP算法详解的转载 ...
- 真正理解KMP算法
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4403560.html 所谓KMP算法,就是判断一个模式串是否是一个字符串的子串,通常的算法当 ...
- 字符串匹配算法之 kmp算法 (python版)
字符串匹配算法之 kmp算法 (python版) 1.什么是KMP算法 KMP是三位大牛:D.E.Knuth.J.H.MorriT和V.R.Pratt同时发现的.其中第一位就是<计算机程序设计艺 ...
- 串匹配算法讲解 -----BF、KMP算法
参考文章: http://www.matrix67.com/blog/archives/115 KMP算法详解 http://blog.csdn.net/yaochunnian/artic ...
- BZOJ 1009 HNOI2008 GT考试 KMP算法+矩阵乘法
标题效果:给定的长度m数字字符串s.求不包括子s长度n数字串的数目 n<=10^9 看这个O(n)它与 我们不认为这 令f[i][j]长度i号码的最后的字符串j位和s前者j数字匹配方案 例如,当 ...
- (原创)白话KMP算法详解
引子:BF暴力算法 KMP算法知名度相当高,燃鹅其理解难度以及代码实现对于初学数据结构和算法的同学并不友好,经过两天的总结,详细总结KMP算法如下: 初学串的模式匹配时,我们都会接触到,或者说应该能想 ...
- 串的模式之kmp算法实践题
给定两个由英文字母组成的字符串 String 和 Pattern,要求找到 Pattern 在 String 中第一次出现的位置,并将此位置后的 String 的子串输出.如果找不到,则输出“Not ...
随机推荐
- python 继承机制(子类化内置类型)
1. 如果想实现与某个内置类型具有类似行为的类时,最好的方法就是将这个内置类型子类化. 2. 内置类型子类化,其实就是自定义一个新类,使其继承有类似行为的内置类,通过重定义这个新类实现指定的功能. c ...
- 实验四:划分多个VLAN
1.配置图 2.配置命令 Switch1.Switch2.Switch3的配置是一样的,如下所示:(可直接复制交换机,可以只配置一次) 通过命令查看配置: Switch0的配置如下: 通过命令查看tr ...
- 分析一下 原型模式的 UML 类图 。 复制对象, 深浅拷贝 月经贴 ,请回避
- 缓冲区溢出实例(二)--Linux
原理:crossfire 1.9.0 版本接受入站 socket 连接时存在缓冲区溢出漏洞. 工具: 调试工具:edb: ###python在漏洞溢出方面的渗透测试和漏洞攻击中,具有很大的优势 实 ...
- Ubuntu学习之路2
由于数据越来越多,学习的也稍微多了点,故将一步一步学习到的命令和快捷键继续到这篇博客. 1. 查看隐藏文件和文件夹 Ctrl+H 2. 打开搜索管理器 Alt+F2 3. 查看系统内存 free -h ...
- ios--->泛型
泛型 开发中使用场景: 1.限制集合中的类型,只能检测方法的调用,因为声明的泛型只能存在方法中 2.当一个类在声明的时候,某个对象的属性不确定,只有创建对象的时候才能确定,就可以使用泛型. 使用泛型的 ...
- springIOC源码接口分析(十一):ConfigurableApplicationContext
一 实现接口 关系图: ConfigurableApplicationContext接口实现了三个接口,ApplicationContext, Lifecycle, Closeable, Applic ...
- Vue系列教程(一)基础介绍
什么是Vue.js Vue.js 是目前最火的一个前端框架,React是最流行的一个前端框架(React除了开发网站,还可以开发手机App,Vue语法也可以进行手机App的开发,需要借助Weex) V ...
- https搭建(自签名证书)
博客搬家: https搭建(自签名证书) 上一篇博客探究了https(ssl)的原理,为了贯彻理论落实于实践的宗旨,本文将记录我搭建https的实操流程,使用Apache2+ubuntu+openss ...
- [python之路]学习路线
python基础 #为什么要学python?python在知名公司广泛应用,谷歌.cia.nasa.youtobe.dropbox.instagram.facebook.redhat.豆瓣.知乎.搜狐 ...