【算法】字符串匹配之Z算法
求文本与单模式串匹配,通常会使用KMP算法。后来接触到了Z算法,感觉Z算法也相当精妙。在以前的博文中也有过用Z算法来解决字符串匹配的题目。
下面介绍一下Z算法。
先一句话讲清楚Z算法能求什么东西。
输入为一个字符串s,Z算法可以求出这个字符串每一个后缀与自身的最长公共前缀LCP,Z算法可以求出一个数组z,z[i]表示suffix(i)与字符串本身的最长公共前缀。
接下来,介绍Z算法的具体内容。
记字符串s的长度为n。
Z算法需要维护一对值,记为left和right,简记为L和R。L和R满足s[L,R]为s串的前缀。当i为1的时候,暴力比较s[0,n-1]与s[1,n-1]可得此时的L与R,同时也得到了z[1],即suffix(1)与s本身的LCP。
假设计算至i-1,我们已经得到了当前的L与R,同时也得到了z[1]到z[i-1]的值,现在需要计算z[i]与新的L和R。
1.假设i>R,则说明不存在一个结束于i或者i之后的串,同时这个串本身也为s的一个前缀,否则R不应该小于i。对于这种情况,需要重新计算新的L与R,令L=R=i,暴力比较s与suffix(i),得到z[i]=R-i+1=R-L+1。
2.此时i<=R,令k=i-L,可以断言z[i]>=min(z[k],R-i+1)。因为根据L与R的含义,此时我们可以将L到R视作为字符串的前缀,那么i相对于L的偏移量为k。
如果z[k]<R-i+1,则z[i]必然等于z[k],基于此时,s[k,k+z[k]-1]是s[i,R]的一个前缀,同时在这种情况下L与R不变。
如果z[k]>=R-i+1,根据R的含义可知s[R+1]!=s[R-L+1],z[k]中大于R-i+1的匹配信息因为s[R+1]!=s[R-L+1]而无效,但这并不意味着s[R+1]!=s[R-i+1],此时根据z[k]可以断言z[i]至少是R-i+1,是否可以更大需要再进行计算,令L=i,更新R值,并得到此时的z[i]。
具体实现中,第二种情况的两种子情况可以归一化处理。
给出一个C++实现代码:
void Z(char *s,int n=) {
n=(n==)?strlen(s):n;
z[]=n;
int l=,r=;
for (int i=;i<n;i++) {
if (i>r) {
l=i,r=i;
while (r<n&&s[r-i]==s[r]) r++;
z[i]=r-l;
r--;
}
else {
int k=i-l;
if (z[k]<r-i+)
z[i]=z[k];
else {
l=i;
while (r<n&&s[r-i]==s[r]) r++;
z[i]=r-l;
r--;
}
}
}
}
过程中每个字符至多被L和R扫到一次,Z算法是线性的复杂度。
Z算法解决单模式串匹配的方法很简单,令S为文本串,T为模式串,构造新串P=T+'#'+S,计算z数组,从S在P中开始的位置向后扫描,如果z[i]=length(S),则说明此处有一个匹配。当然其实也可以不加'#',那样子的话判断需要用>=而不是=。相较于KMP,对于解决单模式串匹配,如求所有匹配位置,其实用Z算法求的话是可以做到不用额外空间的(对于字符串拼接,可以不用开一个新的字符串。过程中判断匹配即可,不必保存z数组。),而KMP的话,不保存模式串的next数组,是没办法进行匹配运算的。
【算法】字符串匹配之Z算法的更多相关文章
- 算法——字符串匹配之BM算法
前言 Boyer-Moore算法是一种基于后缀匹配的模式串匹配算法(简称BM算法),后缀匹配就是模式串从右到左開始比較,但模式串的移动依旧是从左到右的.在实践中.BM算法效率高于前面介绍的<KM ...
- 实现字符串匹配的KMP算法
KMP算法是Knuth-Morris-Pratt算法的简称,它主要用于解决在一个长字符串S中匹配一个较短字符串s. 首先我们从整体来把我这个算法的思想. 字符串匹配的朴素算法: 我们容易想到朴素算法, ...
- Luogu 3375 【模板】KMP字符串匹配(KMP算法)
Luogu 3375 [模板]KMP字符串匹配(KMP算法) Description 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来 ...
- 字符串匹配的 Boyer-Moore 算法
上一篇文章,我介绍了 字符串匹配的KMP算法 但是,它并不是效率最高的算法,实际采用并不多.各种文本编辑器的” 查找” 功能(Ctrl+F),大多采用 Boyer-Moore 算法. 下面,我根据 M ...
- 字符串匹配的 KMP算法
一般字符串匹配过程 KMP算法是字符串匹配算法的一种改进版,一般的字符串匹配算法是:从主串(目标字符串)和模式串(待匹配字符串)的第一个字符开始比较,如果相等则继续匹配下一个字符, 如果不相等则从主串 ...
- 字符串匹配的kmp算法 及 python实现
一:背景 给定一个主串(以 S 代替)和模式串(以 P 代替),要求找出 P 在 S 中出现的位置,此即串的模式匹配问题. Knuth-Morris-Pratt 算法(简称 KMP)是解决这一问题的常 ...
- HDU 1711 Number Sequence (字符串匹配,KMP算法)
HDU 1711 Number Sequence (字符串匹配,KMP算法) Description Given two sequences of numbers : a1, a2, ...... , ...
- 字符串匹配(KMP 算法 含代码)
主要是针对字符串的匹配算法进行解说 有关字符串的基本知识 传统的串匹配法 模式匹配的一种改进算法KMP算法 网上一比較易懂的解说 小样例 1计算next 2计算nextval 代码 有关字符串的基本知 ...
- 字符串匹配的KMP算法
~~~摘录 来源:阮一峰~~~ 字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串”BBC ABCDAB ABCDABCDABDE”,我想知道,里面是否包含另一个字符串”ABCDABD”? 许 ...
随机推荐
- WebGIS中自定义互联网地图局部注记的一种方案
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1. 前言 实际项目中我们经常会遇到这样一种场景:地图底图可能是互 ...
- Digital Tutors - Introduction to Scripting Shaders in Unity 学习笔记
1. Overview 2. Understanding Shader definition:code that define what the material can do in the envi ...
- 详解Swing中JTree组件的功能
JTree组件是另外一个复杂组件,它不像 JTable 那样难用,但是也不像 JList 那么容易.使用 JTree 时麻烦的部分是它要求的数据模型. JTree组件的功能来自树的概念,树有分支和叶子 ...
- 第二期培训(PING问题定位指导)心得
一.什么是 PING DOS 命令,一般用于检测网络通与不通 ,也叫时延,其值越大,速度越慢 PING (Packet Internet Grope),因特网包探索器,用于测试网络连接量的程序.Pin ...
- Java 数值类型以及计算
前段时候写了一个对外提供的接口,其中有一个数值校验的计算.在测试的过程中发现5.6-1.6 != 4,在反复的测试过程中发现double类型的数值为有精度丢失的现象,看来还是基础知识不牢固,所以就在网 ...
- Uri API
四中LaunchMode:http://blog.csdn.net/liuhe688/article/details/6754323 onNewIntent:http://www.cnblogs.co ...
- 求助,如何干掉这个不要脸的“流氓”
问题 chrome 第一次打开时,被一个加"7654 导航"的网站捆绑. 查看设置中启动页中,被设置如下: 解决 域名查看,阿里竟然为这样的网站搞隐私保护 尝试 安 ...
- Linux实战教学笔记25:自动化运维工具之ansible (一)
第二十五节 ansible之文件的批量分发 标签(空格分隔): Linux实战教学笔记-陈思齐 ---本教学笔记是本人学习和工作生涯中的摘记整理而成,此为初稿(尚有诸多不完善之处),为原创作品,允许转 ...
- hog特征及其提取方法图示
1 什么是hog特征 hog特征是histogram of gradient的缩写.我们观察图像时,信息更多来自目标边沿的突变.我们计算一块区域内的所有像素处的梯度信息,即突变的方向和大小,然后对36 ...
- Android中的几种多线程实现
有以下几种方式: 1)Activity.runOnUiThread(Runnable) 2)View.post(Runnable) ;View.postDelay(Runnable , long) 3 ...