首页 > 其他分享 >Z函数

Z函数

时间:2023-05-30 10:36:17浏览次数:26  
标签:匹配段 暴力 扩展 KMP 我们 函数

Z 函数是的意义是对于字符串的后缀 \(i\),其最长的前缀使得存在原串的一个前缀和它相同。

我个人认为 Z 函数是简单于 KMP 的,因为 KMP 的思想是利用前面的答案递归调用计算新的位置,而 Z 函数是简单的递推,只需要一个原先计算的结果就能得出答案,不需要递归。

Z 函数的核心思想是匹配段思想,我们一个 \([i,i+z_i-1]\) 称为一个匹配段。而当我们递推计算 Z 函数的时候,我们总是找到当前右端点最靠右的匹配段。

image

然后我们考虑最右匹配段能给我们提供什么信息。它告诉我们 \([1,r-l+1]\) 和 \([l,r]\) 是相同的。那么对于 \(j=r-l+1-(r-i)=i-l+1\),有 \([j,r-l+1]\) 和 \([i,r]\) 相同。

所以,如果 \(z_j<r-l-z_j+2\),那么意味着 \([j,j+z_j-1]\) 和 \([1,z_j]\) 匹配并且 \(j+z_j\) 和 \(z_j+1\) 不匹配。那么对于 \(z_i\),这也成立。\(z_i=z_j\)。

image

然后,如果 \(z_j\ge r-l-z_j+2\),我们就能确定 \([j,r-l+1]\) 就是匹配的,\([i,r]\) 是匹配的。但是因为 \([i,r]\) 后面的部分不一定和 \(r-l+1\) 后面的匹配,所以我们最多直接套用 \(r-i+1\) 的长度,后面的都需要暴力扩展。

image

我们观察发现,每次暴力扩展,一定在 \(r\) 之后进行。也就是每次暴力扩展至少将最右匹配段增加 \(1\),所以暴力扩展的总次数不会超过 \(O(n)\)。

然后,我们就得到了 Z 函数的完整计算方法。

inline void buildz(){
	int l=1,r=0;z[1]=0;
	rp(i,n)z[i]=0;
	rep(i,2,n){
		if(r>=i)z[i]=max(0,min(r-i+1,z[i-l+1]));
		while(i+z[i]<=n&&s[i+z[i]]==s[z[i]+1])z[i]++;
		if(z[i]>r)l=i,r=i+z[i]-1;
	}
}

标签:匹配段,暴力,扩展,KMP,我们,函数
From: https://www.cnblogs.com/jucason-xu/p/17442525.html

相关文章

  • 【python】函数返回值,返回多个值(返回元组)
    函数返回值,返回多个值(返回元组)实例1:#定义函数,有多个返回值(返回元组)defmeasure():"""测量温度和湿度"""print("测量开始...")temp=39wetness=50print("测量结束...")#元组-可以包含多个数据,因此可以使用元组让函数一次返回多个值......
  • 【python】内置函数list
    内置函数listlist()方法用于将元组转换为列表。注:元组与列表是非常类似的,区别在于元组的元素值不能修改,元组是放在括号中,列表是放于方括号中。#!/usr/bin/python#-*-coding:UTF-8-*-aTuple=(123,'runoob','google','abc');aList=list(aTuple)print("列表......
  • 【python】内置函数enumerate
    内置函数enumerateenumerate()函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在for循环当中。 语法:enumerate(sequence,[start=0])参数sequence:一个序列、迭代器或其他支持迭代对象。start:下标起始位置的值......
  • vscode 自定义代码字体颜色,局部变量、全局变量、函数、宏、属性
    vscode自定义代码字体与颜色风格在setting.json中修改即可:在这里插入图片描述"editor.semanticTokenColorCustomizations":{       "enabled":true,//enableforallthemes       "rules":{           "*.static":{             ......
  • 12)自定义函数
     1、创建自定义函数语法:createfunction函数名(参数1,参数2,...)returns返回值数据类型begin函数体return语句;end;要注意:1)、自定义函数是数据库的对象,创建时,需要指定该函数属于哪个数据库;2)、同一个数据库内,自定义函数不能和已有的函数名重名;3)、函数必须......
  • 第五单元 函数(方法)
    1.函数(方法)的简介函数,在C#中更多的被称为方法。它表示一个的类所具有的行为(方法,函数)。方法的作用封装一些公共的代码,以达到功能重复利用,减少代码冗余。例如,我们经常要进行输入,输出,系统于是帮我们封装好了Console.WriteLine(),Console.ReadLine()等方法。一个方法是把一......
  • Jmeter函数助手36-P
    P函数用于获取jmeter属性值。类似property函数属性名称:填入jmeter的属性名称默认值:缺省值,当获取属性值为空时则返回该值 1、填入属性名称获取属性值${__P(language,)} ......
  • Jmeter函数助手35-property
    property函数用于获取jmeter属性值。属性名称:填入jmeter的属性名称存储结果的变量名(可选)默认值:缺省值,当获取属性值为空时则返回该值 1、查看jmeter全局属性,测试计划右键“添加”->非测试元件->属性显示2、填入属性名称获取属性值${__property(language,,)}${__prop......
  • 通义千问预体验,如何让 AI 模型应用“奔跑”在函数计算上?
    立即体验基于函数计算部署通义千问预体验:https://developer.aliyun.com/topic/aigc_fcAIGC浪潮已来,从文字生成到图片生成,AIGC的创造力让人惊叹,更多人开始探索如何使用AI提高生产效率,激发更多创作潜能,然而在实际应用中,AI技术的高门槛仍然让很多人望而却步,普通开发者或者没......
  • 函数的对象和装饰器概念
    名称空间的作用域名称空间作用域:变量能够作用的范围1.内置的名称空间在程序的任何阶段任何位置都可以使用(全局有效)2.全局的名称空间在程序的任何阶段任何位置都可以使用(全局有效)3.局部的名称空间在函数内部有效(局部有效) global和nonlocal关键字的......