首页 > 其他分享 >Z函数(扩展KMP)

Z函数(扩展KMP)

时间:2024-10-17 10:21:46浏览次数:8  
标签:包住 15 函数 18 扩展 len KMP 20

扩展KMP(Z函数)

Z数组

简单理解

\(Z[i]\) 表示字符串从i出发,与整体相比有多长的公共前缀

a a a b a a c
7 2 1 0 2 1 0

可以先理解马拉车再来看

首先,设置两个类似的东西,关键点 \(c\) 和最右边界 \(r\) ,表示 \(Z[c]\) 是目前所有 \(Z\) 中,\(i+Z[i]\) 最右边的那个

对于:

				  r
0  1  2  3  4  5  |
15 16 17 18 19 20 | 21 22

假定 Z[15]=6,Z[3]=3,此时c=15,r=20

现在的 \(i\) 到达18,那么通过Z数组知道 \(s[18]==s[3]\)

由于 \(Z[15]\),则0=15,1=16,2=17,3=18,4=19,5=20
由于 \(Z[3]\),则0=3,1=4,2=5

所以0=18,1=19,2=20,\(Z[18]=3\)

类似马拉车的 \(2*i-1\),这里相当于 \(Z[18]=Z[18-c]\)

理解了以上部分,接下来开始细节分类

细节分类

参考左程云,他讲的巨详细

  1. i没有被r包住,那么以i为出发点直接扩展

    • 这个就正常比较
  2. i被r包住,但是前点 i-c 的扩展长度,对应在大扩展区域以内,直接确定z[i] = z[i-c]

  3. i被r包住,但是前点 i-c 的扩展长度,对应在大扩展区域的边界,从r之外的位置进行扩展

    • 这个情况和上面举得例子一样,我们只知道\(s[20]=s[5]=s[2]\) ,但是不知道\(s[21]\)的信息
  4. i被r包住,但是前点 i-c 的扩展长度,对应在大扩展区域以外,直接确定z[i] = r - i

    • 这个看似可以像第三点那样拓展,实际上已经确定
    • 还是上面的例子,只有\(Z[3]\) 改成5,则0=3,1=4,2=5,3=6,4=7
    • 在\(Z[15]=6\)的情况下,\(s[21]!=s[6]=>s[21]!=s[3]=>Z[15]=min(Z[i-c],r-i)\)

这一part结束!

CODE

如下,先通过rc来获取最小答案

然后while能处理1、3情况,向外拓展,会直接跳出24情况,因为现实状况就是再外扩是不同的

z[0] = n;
for (int i = 1, c = 1, r = 1, len; i < n; i++) {
	// r没包住i,设置0
	// 如果包住了,那么i到右边界和关键点c的扩充长度
	len = r > i ? min(r - i, z[i - c]) : 0;
	// len现在是最小的长度,现在再看看能不能扩的更远
	while (i + len < n && s[i + len] == s[len]) len++;
	if (i + len > r) {
		r = i + len;
		c = i;
	}
	z[i] = len;
}

e数组

对于字符串A B

\(e[i]\) 表示 \(A[i\cdots n]\) 和 \(B\) 的最长前缀

假定 e[15]=6,z[3]=3,此时c=15,r=20

B:0  1  2  3  4  5 
A:15 16 17 18 19 20

根据 \(e[15]\),有:\(A[15]=B[0],A[16]=B[1],A[17]=B[2],A[18]=B[3]\)

根据 \(z[3]\),有:\(B[0]=B[3],B[1]=B[4],B[2]=B[5]\)

有:\(A[18]=B[0],A[19]=B[1],A[20]=B[2]\)

简单说就是 \(e[i]=z[i-c]\)

// a[i...] 与 b[0...]的最长公共前缀
void eArray(string &a, string &b, int n, int m) {
    for (int i = 0, c = 0, r = 0, len; i < n; i++) {
        // r没包住i,设置0
        // 如果包住了,那么i到右边界和关键点c的扩充长度
        len = r > i ? min(r - i, z[i - c]) : 0;
        // len现在是最小的长度,现在再看看能不能扩的更远
        while (i + len < n && len < m && a[i + len] == b[len]) len++;
        if (i + len > r) {
            r = i + len;
            c = i;
        }
        e[i] = len;
    }
}

标签:包住,15,函数,18,扩展,len,KMP,20
From: https://www.cnblogs.com/lulaalu/p/18471500

相关文章

  • Python join()函数使用详解
    在Python中,join()函数是字符串的一个方法,用于将一个可迭代对象(如列表)中的元素连接成一个字符串。join()函数的语法如下:string.join(iterable)其中,string是连接中的字符串,iterable是要连接的可迭代对象。下面是join()函数的使用示例:#连接列表中的元素my_list=['Hello',......
  • Java 8 的 Lambda、函数式接口、Stream 用法和原理
    我是风筝,公众号「古时的风筝」。一个兼具深度与广度的程序员鼓励师,一个本打算写诗却写起了代码的田园码农!文章会收录在JavaNewBee中,更有Java后端知识图谱,从小白到大牛要走的路都在里面。公众号回复『666』获取高清大图。就在今年Java25周岁了,可能比在座的各位中的一些......
  • Python基础07_推导式&函数
    目录一、推导式1、列表推导式2、字典推导式3、集合推导式4、元组推导式二、函数1、定义函数1.1def语句1.2函数的调用1.3return语句2、函数参数3、返回值4、匿名函数5、变量作用域6、函数的内存分配7、函数自调用(递归)一、推导式 Python推导式是一种独......
  • 如何用axios发送ajax请求(函数)
    在上篇文章的基础上将格式改为:btns[2].onclick=function(){axios({//请求方法method:'POST',url:'/axios-server',params:{vip:10,......
  • 编程语言-Object Pascal语言的面向对象扩展
    ObjectPascal是经典编程语言Pascal的一个扩展版本,引入了面向对象编程(OOP)的关键特性,如类与方法。这一革新性发展是在Pascal的创始人NiklausWirth的协商下,由LarryTesler带领的团队在苹果公司完成的。起源ObjectPascal的前身可以追溯到名为Clascal的语言。Clasc......
  • YCM中previewwindow显示函数类型信息如何实现
    intro在使用YCM的自动提示功能时,可以注意到选择complete提供的条目时,窗口的上面还有一个小窗口提示这个函数的声明信息,包括了函数的参数列表和类型信息。这个对写代码非常有用,对于一段时间不看的函数,很容易记不得函数的参数列表和各自的类型信息,以至于在官方issue中希望提供一个......
  • 非加密哈希函数库-SpookyHash
    地址:https://burtleburtle.net/bob/hash/spooky.htmlSpookyHashisapublicdomainnoncryptographichashfunctionproducingwell-distributed128-bithashvaluesforbytearraysofanylength.Itcanproduce64-bitand32-bithashvaluestoo,atthesames......
  • php部分函数及命令
    lsls:这是一个在Unix/Linux系统中广泛使用的命令,用于列出目录内容。file_get_contents()file_get_contents()把整个文件读入一个字符串中。<?phpechofile_get_contents("test.txt");?>将输出这个文本的内容preg_matchpreg_match函数用于执行一个正则表达式匹......
  • 二次函数与圆的综合(初三)
    专题:二次函数+圆\(\qquad\qquad\)题型:隐圆+轨迹\(\qquad\qquad\)难度系数:★★★★★ (2024年湖北模拟预测)如图,抛物线\(y=-x^2+3x+4\)与\(x\)轴分别交于\(A\),\(B\)两点(点\(A\)在点\(B\)的左侧),与\(y\)轴交于点\(C\).(1)直接写出\(A\),\(B\),\(C\)三点的坐标;(2)如图(1),\(P\)......
  • 高等数学 5.5 反常积分的审敛法 Γ函数
    文章目录无穷限反常积分的审敛法无界函数的反常积分审敛法三、Γ\GammaΓ函数无穷限反常积分的审敛法定理1设函数f(x)f(x)f(x)在区间[a,+∞)[a,+\infty)[a,+∞)上连续,且f(x)⩾0f(x)\geqslant0f(x)⩾0.若函数F(x)=∫axf(t)dtF(x)=\int_a^xf(t)\mathrm{d}t......