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 ...
随机推荐
- 开始使用Manjaro
Manjaro是什么? 一个基于Arch系列,开源的linux发行版 Mnajrao官网了解更多,这里不做更多阐述内容 为什么使用Manjaro 第一点,为了方便自己隔离腾讯网游 第二点,更方便的学习 ...
- 异数OS TCP协议栈测试(二)--短连接篇
异数OS TCP协议栈测试(二)--短连接篇 本文来自异数OS社区 github: 异数OS-织梦师(消息中间件)群: 476260389 测试目标 TCP 短链接IO性能测试,Client Se ...
- [洛谷P4178] Tree (点分治模板)
题目略了吧,就是一棵树上有多少个点对之间的距离 \(\leq k\) \(n \leq 40000\) 算法 首先有一个 \(O(n^2)\) 的做法,枚举每一个点为起点,\(dfs\) 一遍可知其它 ...
- 电脑开机后多了OneKey Ghost启动选项怎么解决
原文地址:http://www.xitongcheng.com/jiaocheng/dnrj_article_18745.html 大多数用户在使用OneKey Ghost安装电脑系统后,会在开机启动 ...
- pywin32 获取 windows 的窗体内文本框的内容
用 spy++去确认找到了文本框的句柄了. 用函数 win32gui.SendMessage 获取不了文本框的文本内容,用 str 类型的参数接收获取的内容的话没有获取到东西,而用 PyBuffer ...
- 创建自定义路由处理程序(Creating a Custom Route Handler) | 定制路由系统| 高级路由特性 |精通ASP-NET-MVC-5-弗瑞曼
自定义实现 IRouteHandler
- 上线前一个小时,dubbo这个问题可把我折腾惨了
前因 那是一个月黑风高的夜晚,不管有没有圆圆的月亮,都无法解救要加班的我.这就是苦涩的人生啊! 那天正好是春节回家的日子,定了晚上的票,然后还是上线的日子. 测试在做回归测试的时候,发现一个老功能报错 ...
- node使用art-template的过滤器
引言 art-template过滤器在我看来,其实就是定义一个函数,模板字符串通过调用该函数处理相关的数据,得到相应的返回结果,显示在页面上.因此我们可以注册一个过滤器,处理相关的数据.这里使用nod ...
- 如何快速搭建一个 Node.JS 项目并进入开发?
了解:如何快速搭建一个项目并进入开发? 在此不概述 Node.JS 的历史以及发展过程. 因为之前接触过通过 Java 开发语言,所以明确地知道一个服务器所需的文件,以及一个服务器所需要的操作. 那么 ...
- Java使用自定义类加载器实现热部署
热部署: 热部署就是在不重启应用的情况下,当类的定义即字节码文件修改后,能够替换该Class创建的对象.一般情况下,类的加载都是由系统自带的类加载器完成,且对于同一个全限定名的java类,只能被加载一 ...