对于一个长度为 nn 的字符串 ss,定义函数 z[i]z[i] 表示ss 和s[i,n−1]s[i,n−1](即以 s[i]s[i] 开头的后缀)的最长公共前缀(LCP)的长度,则 zz 被称为 ss 的Z 函数。特别地,z[0]=0z[0]=0。国外一般将计算该数组的算法称为 Z Algorithm,而国内则称其为 扩展KMP。
定义一个长度为 n 的字符串 s,定义 zi 表示s 和s[i,n] 的lcp(最长公共前缀),称 z 为s 的Z 函数。朴素算法暴力枚举,时间复杂度:O(n2)线性算法我们首先考虑顺次处理 z1,z2,…,zn,当枚举到 i 时,也就是说 z1,…,zi−1 是已经求得了。我们再来定义名词 Z-box :指与字符串 s 匹配的前缀区间...
func z_func(nums []int) []int { n := len(nums) z := make([]int, n) zl, zr := 0, 0 for i := 1; i < n; i++ { if i >= zr { // 不在zbox中,直接查找新的zbox zr = i for ; zr < n && nums[z[i]] == nums[zr]; zl, zr, z[i] = i, zr+1, z[i]+1...
扩展 KMP 求的东西和 KMP 不同。具体是什么呢?我们定义一个序列z,其中z[i]表示s与s[i,n]的最长公共前缀(LCP)的长度。扩展 KMP 就可以用来求解这个序列z。为了方便起见,我们规定z[1]=0。如果需要z[1]的原本含义(即z[1]=n)的话,在算法结束后把它改回去即可。
voidGetZFunc(conststd::stringstr){intlen = str.length();for(inti =1; i < len; i++)while(i + z[i] < len && str[z[i]] == str[i + z[i]]) z[i]++;return; } Z 算法(在O(n)O(n)时间内求出 Z 函数) 类似KMP 字符串匹配中求ππ和 Manacher 算法中求最长回文时的优化思路,...
扩展KMP(Z 函数)学习笔记,扩展$KMP$就是对于两个字符串$s1,s2$,求$s1$的每一个后缀和$s2$的$LCP$长度。个人感觉明明叫$ExKMP$却和$KMP$毫无关系,反而与$Manacher$有着异曲同工之妙。
Z函数 求一个字符串str以第i位开始的后缀与str的最长公共前缀(lcp) z[i]表示第i位开始的后缀与str的最长公共前缀 Z box 是字符串str中一个区间[l,r]满足str[l,r]是str的前缀,不要求最长,会随着i的变化而移动 在位置i时,[l,r]必须包含i,r尽可能max ...
z[i] = z[i-p0]; else { now = max( p0+z[p0]-i,0 ); while( now+i<pl && p[now]==p[now+i] ) now++; z[i] = now; p0 = i; } } } void exkmp() { getZ(); int now = 0, p0 = 0; while( now<pl && now<sl && p[now]==s[now] ) now++; ...
视频地址:【koko的算法课堂】KMP匹配、Z函数、扩展KMP 铁傀儡的二代 粉丝:13文章:1 关注 题目大意 已知str1和str2分别为主串和模式串,求str所有子串中和模式串相等的串的下标位置(这个一求出来,个数也就迎刃而解了) 首先KMP分为两步 1.求模式串配对 ...
P5410 【模板】扩展 KMP(Z 函数) 裸的扩展kmp。 我的ex-kmp数组下标从0开始,用的时候处理一下就好了。 #include<iostream>#include<string>#include<cstdio>#include<cstring>#definell long longusingnamespacestd;constintmaxn=20001000;chars[maxn],t[maxn];ll ex[maxn],nt[maxn];intn,m;voidget_...