Z函数(扩展KMP)

news/2024/10/20 20:43:42

扩展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;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/72572.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

2024北森题库(含答案)

"2024北森题库(含答案)"揭示了这是一份针对教育和考试领域的资源,特别是与北森题库相关的练习题目和解答。北森题库通常指的是由北森公司提供的各类考试模拟题集,涵盖了诸多考试科目,如公务员考试、事业单位招聘、教师资格证考试等。这份资料对于备考者来说是一…

页面下拉刷新事件

启用下拉刷新 配置下拉刷新样式监听页面的下拉刷新事件 停止下拉刷新样式

2024 最新 jetbrains GoLand 2024.1.6 激活(亲测可用)

注意:接下来本文分享免费激活 GoLand 等Jetbrains全家桶工具,一直支持到最新版本2024.1.6。 1.下载安装IDEA (mac、window、linux都支持) 大家直接在官网下载最新版本,登陆官网,下载最新版本2024.1.4。一步一步确定安装,然后打开 这里提示输入激活码,先关闭应用!!!…

2024 最新 jetbrains DataGrip 2024.1.6 激活(亲测可用)

注意:接下来本文分享免费激活 IDEA 等Jetbrains全家桶工具,一直支持到最新版本2024.1.6。 1.下载安装IDEA (mac、window、linux都支持) 大家直接在官网下载最新版本,登陆官网,下载最新版本2024.1.4。一步一步确定安装,然后打开 这里提示输入激活码,先关闭应用!!!2.…

2024 最新 jetbrains WebStorm 2024.1.6 激活(亲测可用)

注意:接下来本文分享免费激活 IDEA 等Jetbrains全家桶工具,一直支持到最新版本2024.1.6。 1.下载安装IDEA (mac、window、linux都支持) 大家直接在官网下载最新版本,登陆官网,下载最新版本2024.1.4。一步一步确定安装,然后打开 这里提示输入激活码,先关闭应用!!!2.…

网站修改公司名称?怎么修改网站密码?

修改公司名称登录后台管理:首先,你需要登录到网站的后台管理系统。通常,这可以通过访问类似 yourwebsite.com/admin 的地址来完成。找到设置选项:登录后,寻找“设置”或“配置”相关的选项。这可能在侧边栏或顶部菜单中。编辑公司信息:在设置页面中,找到与公司信息相关的…

网站模板修改文件?网站模板怎样修改?

网站模板修改文件 修改网站模板文件通常涉及以下几个步骤,具体操作可能会因不同的建站平台或CMS(内容管理系统)而有所不同。以下是通用的步骤: 1. 登录后台管理访问后台:打开浏览器,输入您网站的后台管理地址,通常是类似于 https://yourwebsite.com/admin 的URL。 登录:…

数据库修改网站密码?网站管理后台修改?

数据库修改网站密码备份数据库:在直接操作数据库之前,确保先备份数据库,以防出现意外情况。 访问数据库:通过数据库管理工具(如phpMyAdmin)或命令行工具(如MySQL命令行客户端)连接到数据库。 定位用户表:找到存储用户信息的表,通常命名为 users 或类似的名称。 查找用…