学渣乱搞系列之扩展KMP的那点事

扩展KMP牵涉了一些相对运动的姿势,比较费解!本学渣看了一天的扩展KMP,打算写点东西。。。本文看后,出现的后果本人一概不负责。毕竟我不是很会表达。

扩展KMP是搞什么灰机的?本学渣所知道的扩展KMP是来解集训篇那道字符串题的。有了犯罪动机,现在就要下手。不要以为扩展KMP就以为与KMP关系暧昧。屁大点事,两个根本不是一个东西。只是有点思想是一致的,就是利用已经匹配的信息避免一些不必要的匹配。

以此提高匹配速度。不过扩展KMP也能干KMP干的事。但是速度没KMP那么快。

扩展KMP要造两个数组,一个Next数组,一个exd数组,前一个是存储模式串的后缀串的最长前缀长,exd数组就是我们的终极目标!我们的终极目标是干吗?泡妞把妹?AC?。。。。。。

后缀造了造前缀?下面讲下如何求next吧,网上很多教程都是讲求exd的。假设s就是串t。

Exd[i] = s[i….n]与t[1..m]的最大前缀长度。(i > = 0 && I < n)

假设s[a…p] == t[0..p-a]表示a位置与模式串所能达到的最大前缀长度。

那么我们有a <= k <= p 且 s[k…p]   ==   t[k-a…p-a]

为什么啊?相对位置啊k – a = x – 0;    x = k-a;

现在假设我们要求next[i]。  i > k ;

还记得我们上一次匹配吗??那时候的s[a]是与t[0]对齐。现在我们利用的就是这次对齐。

求next[i]就是要把t[0]与s[i]对齐。那么next[i-a]存的是什么呢?是不是s[a]与t[0]对齐时,

S[i]是不是与t[i-a]对齐的呢?I – a = x – 0 ;  x = i-a;

那么从next[i-a]记录的是什么东西呢?是不是表示t[i-a]与t[0]对齐时的最长前缀么?

假设L  =  next[i-a];

求的是next[i] 此时是把s[i]与t[0]对齐,前面有t[i-a]与t[0]的最大前缀,t[i-a]又正是上次对着s[i]的,所以L很有可能就是s[i]与t[0]对齐时的最长前缀。为什么是很有可能呢?

设p = a + next[a]-1;  上次的匹配范围是多少来着?s[a,p] == t[0,p-a]  匹配i时,i+L-1很有可能超过p,超过的世界,那是我们没有匹配过的。所以要单独处理下。

而i+L-1 < p 则一切尽在匹配之中,exd[i]就等于L,没有等于啊。。。。因为无法确定后面的是不是失配了。。。

为什么不能再长呢?因为因为,t[i-a…p-a]只有L长的与t[0…p-a]匹配啊。。。

为什么求出next[i],因为next[a]已经求出了,i-a<= i 求next[i]时,next[i-a]早已求出。。。。。

好了,现在大家终于都不理解啥是扩展KMP了。欢迎各种乱评。。。

show me your code?

 1 int next[200];
 2 char p[] = "aaaa";
 3 void getNext(){
 4     int i,k = 1;
 5     for(i = 0; p[i+1] && p[i] == p[i+1]; i++);//暴力解决
 6     next[1] = i;
 7     for(i = 2; p[i]; i++){
 8         int t = k+next[k],j = i+next[i-k];
 9         if(j < t) next[i] = j;
10         else{
11             for(j = t-i; p[i+j] && p[i] == p[i+j]; j++);
12             next[k = i] = j;
13         }
14     }
15 }

学渣乱搞系列之扩展KMP的那点事,布布扣,bubuko.com

时间: 2024-10-27 05:11:57

学渣乱搞系列之扩展KMP的那点事的相关文章

学渣乱搞系列之dp斜率优化

学渣乱搞系列之dp斜率优化 By 狂徒归来 貌似dp的斜率优化一直很难搞啊,尤其是像我这种数学很挫的学渣,压根不懂什么凸包,什么上凸下凸的,哎...说多了都是泪,跟wdd讨论了下,得出一些结论.本文很大部分参考了大神Accept的文章,不过此神貌似早已绝迹江湖,这篇文章写得好,也写得很差,前半部分叙述得很好,可是关键,关键部分说得很乱,有些许错误,很多大神都进行了评论指出,但是大神Accept貌似没有修改的意思,故重新总结下,以便自己以后查阅和复习啊. 下面看一个例题Print Article.

学渣乱搞系列之网络流学习

学渣乱搞系列之网络流学习 几篇优秀的文章,鉴于本学渣目前功力不够,还不能掌握网络流的精髓要义.故载几篇牛文. Dinic算法: Comzyh的博客 Lich_Amnesia

学渣乱搞系列之字符串滚动哈希

学渣乱搞系列之字符串滚动哈希 by 狂徒归来 我们假定字符串S = S1S2S3S4S5S6S7S8S9. 我们定义哈希函数为 H(S) = (S1bm-1+S2bm-2+S3bm-3+...+Smb0)mod h.其中b是基数,相当于把字符串看成b进制数. b与h为合适的互素的常数. 如何求取字符串内长度为m的一段的字符子串的哈希值? 假定m = 3. 先求取H([S1...S3]) =  S1b2+S2b1+S3b0. 求取H([S2...S4]) = H([S1...S3])*b + S4

学渣乱搞系列之后缀数组

学渣乱搞系列之后缀数组 by 狂徒归来 后缀数组,其nlogn的构造方法,比较麻烦,十几个循环,基数排序?计数排序?各种排序,各种凌乱,学渣表示鸭梨很大啊!学渣从<挑战程序设计竞赛>中偷学了一点nlog2n的构造方法. 字符串后缀(Suffix)是指从字符串的某个位置开始到其末尾的字符串子串.我们认为原串和空串也是后缀. 后缀数组(Suffix Array)指的是将某个字符的所有后缀按字典序排序后得到的数组.排序方式很多,时间复杂度也不同.有基数排序的倍增法o(nlogn),有DC3构造方法o

学渣乱搞系列之Tarjan模板合集

学渣乱搞系列之Tarjan模板合集 by 狂徒归来 一.求强连通子图 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <climits> 7 #include <vector> 8 #include <queue> 9 #incl

HDU 4333 Revolving Digits [扩展KMP]【学习笔记】

题意:给一个数字,每一次把它的最后一位拿到最前面,一直那样下去,分别求形成的数字小于,等于和大于原来数的个数. SAM乱搞失败 当然要先变SS了 然后考虑每个后缀前长为n个字符,把它跟S比较就行了 如果用后缀家族的话复杂度要加上log,本题会TLE吧 求一个串S的每个后缀与另一个串T的最长公共前缀可以用扩展KMP!复杂度O(n+m) 看课件吧 从1开始写真不容易以后再也不从1开始了,判断位置好麻烦好容易错 next[i]=LCP(T[i,m],T) extend[i]=LCP(S[i,n],T)

【BZOJ-2937】建造酿酒厂 前缀和 + 展环为链 + 乱搞

2937: [Poi2000]建造酿酒厂 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 70  Solved: 24[Submit][Status][Discuss] Description Abstinence岛上的居民很喜欢饮用纯酿的啤酒.迄今为止,他们都是从波兰进口啤酒,自己不生产.但今年岛上的一个城市决定建造一个酿酒厂,供给其他城市的啤酒需求. 岛上所有的城市都环绕在海岸线上,相邻两城之间用高速公路连接(也就是说,它们近似分布在一个圆上).

字符串(1)---KMP &amp; 扩展KMP &amp; Manacher

练习:点击打开链接 字符串也是ACM中的重头戏,基本内容有KMP ,扩展KMP, Manacher ,AC自动机,后缀数组,后缀自动机.按照专题来做共分三部分. LCS LIS LCIS不知道算不算....点击打开链接 小技巧:匹配问题不区分大小写,则将其全部转为小写. 暴力匹配: 用strstr函数就能解决       I M N Z(枚举长度 三份) 一.KMP算法 解决单一模式串匹配问题. 利用失配后的nxt数组减少移位,达到O(n)级别.资料自行百度. 延展: 1.求最小循环节 点击打开

KMP、扩展KMP、MANACHER

一.KMP 作用:用于在一个文本串S内查找一个模式串P出现的位置 string str = "bacbababadababacambabacaddababacasdsd"; string ptr = "ababaca"; 如上图,可得在第10与26处包含ptr数组: 暴力做法:暴力for,碰到不一样的直接返回,从后一个开始继续for,最差能到O(n * m) KMP 做法: 主要的思路是跳,比如你一开始从上面例子里的bacbababadababacambabacad