Z Algorithm(扩展KMP)算法笔记

假设给定一个s长度为的n字符串。那么这个字符串的 z-function (“zet-function”)是一个长度为 的数组,其中的 -th 元素等于最大字符数,从 position i开始,i与字符串的第一个字符n重合。

换句话说,z[i]它是s字符串及其i-th 后缀的最大通用前缀。

注意:在本文中,为了避免歧义,我们将字符串视为0索引,即字符串的第一个字符具有索引0,最后一个n-1字符是。

z 函数的第一个元素通常z[0]被认为等于零。

本文描述了一种计算z函数的O (n)算法,以及该算法的各种应用。

例子

下面是针对多个计算的 z 函数的示例:

  • aaaaa
z[0] = 0,
z[1] = 4,
z[2] = 3,
z[3] = 2,
z[4] = 1
  • aaabaaab
z[0] = 0,
z[1] = 2,
z[2] = 1,
z[3] = 0,
z[4] = 2,
z[5] = 1,
z[6] = 0
  • abacbaa
z[0] = 0,
z[1] = 0,
z[2] = 1,
z[3] = 0,
z[4] = 3,
z[5] = 0,
z[6] = 1

朴素算法

以下算法基本实现时间复杂度O (n^2):

    public static int[] zFunction(String s){int n=s.length();char[]sa=s.toCharArray();int[] z=new int[n];for(int i=1;i<n;i++){while(i+z[i]<n&&sa[z[i]]==sa[i+z[i]]){++z[i];}}return z;}

对于每个位置i,我们只需从零开始迭代它的z[i]答案,直到我们发现不匹配或到达线的末尾。

计算 z 函数的有效算法

为了获得有效的算法,我们将逐个计算值,从i=1到,同时在计算下一个值时,我们将尝试n-1充分利用已经计算出的值z[i]。

为简洁起见s,我们将与字符串前缀匹配的子字符串称为匹配栏。例如,您要查找的z函数z[i]的值是从position开始(并将在positioni,i+z[i]-1结束)的最长匹配段。

为此,我们将保持重合最[左;r]右边段的坐标,即我们将存储在所有检测到的段的右侧结束的坐标。从某种意义上说,索引r是算法已经扫描了我们的字符串的边界,其他一切都还不知道。

然后,如果我们要计算z函数的下一个值的当前索引是i,我们有以下两个选项之一:

  • i>r—换句话说,目前的情况超出了我们已经处理的情况。
    然后我们将使用一个简单的算法进行搜索z[i],即只尝试、等的值z[i]=0。请注意,最后,如果z[i]结果是,z[i]=1那么我们将不得不更新最右边段[左;r]的坐标——因为它i+z[i]-1保证>0大r于。

  • i≤r—即当前位置位于重合段[左;r]内。
    在这种情况下,我们可以使用已经计算出的z函数的先前值来初始化值,而不是用零,而是用一些可能更高的数字来初始化值z[i]。

为此,请注意子字符串s[l…r]重合s[0…r-l]。这意味着作为初始近似值,z[i]我们可以从直线中获取相应的值,即s[0…r-l]值z[i-l]。

但是,该值z[i-l]可能太大,以至于当应用于某个位置我时,它会“爬出”边界r。这是不允许的,因为我们对右边的符号一无所知,而且它们可能与所需的符号r不同。

让我们举一个这种情况的例子,使用以下行作为示例:

aaaabaa

当我们到达最后一个位置i=6时,当前最右边的行是[5:6]。考虑到此段,该位置将对应6,6-5=1于答案等于z[1]=3的位置。显然,你不能用这样的值初始化z[6],这是完全不正确的。我们可以初始化的最大值是,因为它是1不超过[左;r]行的最大值。

因此,仅z[i]采用以下表达式作为初始近似值是安全的:

z_0[i]=min(r-i+1,z[i-l])。

使用z[i]这样的值初始化后,我们再次使用一个简单的算法,因为在边界之后,一般来说,可以找到z_0[i]线段的延续r,这是我们无法仅用z函数的先前值来预测的巧合。

因此,整个算法由两种情况组成,实际上仅在初始值上有所不同:在第一种情况下,假设它等于零,在第二种情况下,它由根据z[i]指定公式的先前值确定。之后,算法的两个分支都简化为执行一个从指定的初始值立即开始的简单算法。

事实证明,该算法非常简单。尽管他们每个人都我以一种或另一种方式执行一个微不足道的算法,但我们通过获得一种在线性时间内工作的算法取得了重大进展。为什么会这样,在我们介绍算法的实现之后,我们将在下面考虑。

实现

    public static int[] zFunction(String s){int n=s.length();char[]sa=s.toCharArray();int[] z=new int[n];int left=0,right=0;for(int i=1;i<n;i++){if (i<=right){z[i]=Math.min(right-i+1,z[i-left]);}while(i+z[i]<n&&sa[z[i]]==sa[i+z[i]]){++z[i];}if (i+z[i]-1>right){left=i;right=i+z[i]-1;}}return z;}

数组最初填充为z为0。假设当前最右边的重合部分等于[0;0],即一个故意的小部分,其中不会落i下

在循环中,我们首先使用上述算法来确定初始值z[i]——它要么保持为零,要么根据给定的i=1…n-1公式计算。

之后,执行一个简单的算法,试图尽可能地增加该值z[i]。

最后,如果需要[左;r]此更新,则更新匹配的当前最右边部分,即ifi+z[i]-1>r

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql数据库使用mysqlbinlog命令查看数据操作、主从数据同步记录

mysql主从同步时&#xff0c;由于意外的操作&#xff0c;可能会出现下面的错误&#xff1a; Could not execute Update_rows event on table confluence.AO_92296B_AORECENTLY_VIEWED; Can’t find record in ‘AO_92296B_AORECENTLY_VIEWED’, Error_code: 1032; handler erro…

如何使用Python + 百度翻译API 自动大批量免费翻译Excel文件中的外语内容

手里有一个Excel文件,包括了大量的亚马逊德语搜索词(关键词),每个单元格1个,需要翻译为中文。但是文件大小超过了10M,不能使用百度或Google免费的文档功能,如果手工一个个的翻译然后粘贴又太麻烦,于是想到用Python加免费翻译API完成。 一、openpyxl库 用Python编辑处…

Magnet AXIOM取证神器的安装使用方法及详细教程

Magnet AXIOM取证神器的安装使用方法及详细教程 公众号&#xff1a;鱼影安全1.Magnet AXIOM取证工具介绍&#xff1a;2.Magnet AXIOM取证工具安装&#xff1a;第一步&#xff1a;第二步&#xff1a; 3.Magnet AXIOM取证工具使用方法&#xff1a; 公众号&#xff1a;鱼影安全 关…

112.乐理基础-五线谱-五线谱的调号(一)

内容参考于&#xff1a;三分钟音乐社 上一个内容&#xff1a;111.乐理基础-五线谱-五线谱的节奏型、打拍子-CSDN博客 首先需要掌握&#xff0c;下图中的所示的内容&#xff1a;内容可以在 乐理基础 这里找到&#xff0c;名字上带※符号的找不到 首先回顾七个白键触发的大调音…

香港的低价服务器:2024年稳定服务商推荐

对于用户而言&#xff1a;使用香港服务器无非是觉得免备案、或者业务是集中在日本或东南亚地区&#xff0c;无论是哪些因素驱使&#xff0c;其实用户想要的就是一个低价稳定&#xff01;如果服务器都连不上&#xff0c;再便宜又有什么用处。 所以先给各位用户提个醒&#xff0…

day28打卡

day28打卡 93. 复原 IP 地址 见注释 class Solution { public:vector<string> ret;vector<string> restoreIpAddresses(string s) {string ip;dfs(s, 0, ip);return ret;}//n记录小数点个数void dfs(string s, int n, string ip){//n为4if(n 4){//如果字符s没有…

眸思MouSi:“听见世界” — 用多模态大模型点亮盲人生活

文章目录 1. Introduction1.1 APP细节展示2. Demo2.1 论文链接2.2 联系方式3. Experiment3.1 多专家的结合是否有效?3.2 如何更好的将多专家整合在一起?Reference让盲人听见世界,复旦眸思大模型打破视觉界限,用科技点亮新生活 1. Introduction 在这个世界上,视力是探索万…

力扣精选算法100道——和为 K 的子数组[前缀和专题]

和为K的子数组链接 目录 第一步&#xff1a;了解题意​编辑 第二步&#xff1a;算法原理 第三步&#xff1a;代码 第一步&#xff1a;了解题意 数组中和为k的连续子数组&#xff0c;我们主要关注的是连续的&#xff0c; 比如[1,1,1],和为2的子数组有俩个&#xff0c;比如第…

HDL Designer 2021.1 如何将默认编辑器修改为VsCode

第1步 安装Vscode 第2步 添加Vscode至HDL Designer 第3步 更改HDL Designer编译器 第4步 修改结束&#xff0c;在HDL Designer中双击block可使用Vscode编辑verilog

通过无线打通两个路由器

通过无线打通两个路由器 上网向导无线连接 配置比较简单&#xff0c;有些路由器支持有些不支持&#xff0c;支持的大致就是下面的方法&#xff0c;不过不同型号面板不一样&#xff0c;这里主要学习方法&#xff0c;所以不做路由器型号介绍。 重要的事情说三遍&#xff1a;学习要…

云端录制直播流视频,上传云盘

前言 哪一天我心血来潮&#xff0c;想把我儿子学校的摄像头视频流录制下来&#xff0c;并保存到云盘上&#xff0c;这样我就可以在有空的时候看看我儿子在学校干嘛。想到么就干&#xff0c;当时花了一些时间开发了一个后端服务&#xff0c;通过数据库配置录制参数&#xff0c;…

修改数据库字段长度报错如何解决

如果直接修改SQL报错的话&#xff0c;可以考虑【增加备用字段->复制字段值->删除原字段->备用字段改名】的思路进行处理。 执行的时候建议一步一步执行而非批量执行 其中COLUMN_T为备用字段&#xff0c;COLUMN_O为原字段。 -- 根据原字段创建新长度的备用字段 alte…

挑战杯 python+深度学习+opencv实现植物识别算法系统

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于深度学习的植物识别算法研究与实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;4分工作量&#xff1a;4分创新点&#xff1a;4分 &#x1f9ff; 更多…

Java学习笔记2024/2/5

综合练习题 练习一&#xff1a;飞机票 需求: 机票价格按照淡季旺季、头等舱和经济舱收费、输入机票原价、月份和头等舱或经济舱。 按照如下规则计算机票价格&#xff1a;旺季&#xff08;5-10月&#xff09;头等舱9折&#xff0c;经济舱8.5折&#xff0c;淡季&#xff08;1…

【数论】矩阵快速幂

参考&#xff1a;矩阵快速幂算法详细解析 放个板子 int M, n;struct node // 定义一个矩阵类型的结构体 {int m[100][100]; } ans, res; // ans是结果&#xff0c;res是最初的方阵node mul(node A, node B) {int i, j, k;node temp; // 定义一个临时矩阵&#xff0c;存放A…

面试复盘7——后端开发

前言 一面&#xff08;2024-1.25&#xff09; 首先上来是自我介绍。 &#xff08;这里自我介绍时候项目只说了技术栈&#xff0c;没有说内容&#xff0c;不知道好不好&#xff09; &#xff08;在校经历说的一点点口语化了&#xff09; 先问的近期实习经历&#xff0c;和我确…

js和node事件循环区别

javaScript事件循环机制 一、是什么&#xff1f; JavaScript是一门单线程语言&#xff0c;同一时间只能做一件事&#xff0c;但并不意味着单线程就是阻塞&#xff0c;而实现单线程非阻塞的方式就是事件循环。 JavaScript中&#xff0c;所有的任务都可以分为&#xff1a; 同步…

93.网游逆向分析与插件开发-游戏窗口化助手-升级经验数据获取的逆向分析

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;显示游戏数据到小助手UI 码云地址&#xff08;游戏窗口化助手 分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号&#xff1a;852c339f5e4c103390b123e0eaed…

浅析现代计算机启动流程

文章目录 前言启动流程概述磁盘分区格式MBR磁盘GPT磁盘隐藏分区 传统BIOS引导传统BIOS启动流程 UEFI引导UEFI引导程序UEFI启动流程 引导加载程序启动操作系统相关参考 前言 现代计算机的启动是一个漫长的流程&#xff0c;这个流程中会涉及到各种硬件的配置与交互&#xff0c;包…

Python接口自动化测试框架运行原理及流程

这篇文章主要介绍了Python接口自动化测试框架运行原理及流程,文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 本文总结分享介绍接口测试框架开发&#xff0c;环境使用python3selenium3unittestddtrequests测试框…