博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
KMP算法Next()函数的一个应用
阅读量:6932 次
发布时间:2019-06-27

本文共 1671 字,大约阅读时间需要 5 分钟。

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

 

 

 

 

转载地址:http://akmjl.baihongyu.com/

你可能感兴趣的文章
js基础进阶--promise和setTimeout执行顺序的问题
查看>>
mongoose再认识(三)
查看>>
你真的了解RPC吗?
查看>>
Composer简明教程
查看>>
jsonP格式接口实现
查看>>
小窍门-在EXECL表中加入下拉列表
查看>>
INDIGO STUDIO神器!快速创建WEB、移动应用的交互原型工具【转】
查看>>
我的2017云栖之行
查看>>
《Android应用开发与系统改造实战》——导读
查看>>
8天学通MongoDB——第二天 细说增删查改
查看>>
Tomcat7基于Redis的Session共享
查看>>
RxSwift(一)Creating and Subscribing to Observables 创建和订阅观察者
查看>>
从无到有搭建一套组件库
查看>>
DisqusJS - 一个超轻量级的 DISQUS「评论基础模式」的实现
查看>>
【从蛋壳到满天飞】JS 数据结构解析和算法实现-堆和优先队列(二)
查看>>
springboot2新版springcloud微服务,带你了解不一样的springboot2
查看>>
关于进程的一些基础知识
查看>>
2019.5.7_可以休息吗?_函数内省
查看>>
Struts2获取request三种方法
查看>>
我的友情链接
查看>>