求文本与单模式串匹配,通常会使用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算法的更多相关文章

  1. 算法——字符串匹配之BM算法

    前言 Boyer-Moore算法是一种基于后缀匹配的模式串匹配算法(简称BM算法),后缀匹配就是模式串从右到左開始比較,但模式串的移动依旧是从左到右的.在实践中.BM算法效率高于前面介绍的<KM ...

  2. 实现字符串匹配的KMP算法

    KMP算法是Knuth-Morris-Pratt算法的简称,它主要用于解决在一个长字符串S中匹配一个较短字符串s. 首先我们从整体来把我这个算法的思想. 字符串匹配的朴素算法: 我们容易想到朴素算法, ...

  3. Luogu 3375 【模板】KMP字符串匹配(KMP算法)

    Luogu 3375 [模板]KMP字符串匹配(KMP算法) Description 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来 ...

  4. 字符串匹配的 Boyer-Moore 算法

    上一篇文章,我介绍了 字符串匹配的KMP算法 但是,它并不是效率最高的算法,实际采用并不多.各种文本编辑器的” 查找” 功能(Ctrl+F),大多采用 Boyer-Moore 算法. 下面,我根据 M ...

  5. 字符串匹配的 KMP算法

    一般字符串匹配过程 KMP算法是字符串匹配算法的一种改进版,一般的字符串匹配算法是:从主串(目标字符串)和模式串(待匹配字符串)的第一个字符开始比较,如果相等则继续匹配下一个字符, 如果不相等则从主串 ...

  6. 字符串匹配的kmp算法 及 python实现

    一:背景 给定一个主串(以 S 代替)和模式串(以 P 代替),要求找出 P 在 S 中出现的位置,此即串的模式匹配问题. Knuth-Morris-Pratt 算法(简称 KMP)是解决这一问题的常 ...

  7. HDU 1711 Number Sequence (字符串匹配,KMP算法)

    HDU 1711 Number Sequence (字符串匹配,KMP算法) Description Given two sequences of numbers : a1, a2, ...... , ...

  8. 字符串匹配(KMP 算法 含代码)

    主要是针对字符串的匹配算法进行解说 有关字符串的基本知识 传统的串匹配法 模式匹配的一种改进算法KMP算法 网上一比較易懂的解说 小样例 1计算next 2计算nextval 代码 有关字符串的基本知 ...

  9. 字符串匹配的KMP算法

    ~~~摘录 来源:阮一峰~~~ 字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串”BBC ABCDAB ABCDABCDABDE”,我想知道,里面是否包含另一个字符串”ABCDABD”? 许 ...

随机推荐

  1. WebGIS中自定义互联网地图局部注记的一种方案

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.    前言 实际项目中我们经常会遇到这样一种场景:地图底图可能是互 ...

  2. 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 ...

  3. 详解Swing中JTree组件的功能

    JTree组件是另外一个复杂组件,它不像 JTable 那样难用,但是也不像 JList 那么容易.使用 JTree 时麻烦的部分是它要求的数据模型. JTree组件的功能来自树的概念,树有分支和叶子 ...

  4. 第二期培训(PING问题定位指导)心得

    一.什么是 PING DOS 命令,一般用于检测网络通与不通 ,也叫时延,其值越大,速度越慢 PING (Packet Internet Grope),因特网包探索器,用于测试网络连接量的程序.Pin ...

  5. Java 数值类型以及计算

    前段时候写了一个对外提供的接口,其中有一个数值校验的计算.在测试的过程中发现5.6-1.6 != 4,在反复的测试过程中发现double类型的数值为有精度丢失的现象,看来还是基础知识不牢固,所以就在网 ...

  6. Uri API

    四中LaunchMode:http://blog.csdn.net/liuhe688/article/details/6754323 onNewIntent:http://www.cnblogs.co ...

  7. 求助,如何干掉这个不要脸的“流氓”

      问题 chrome 第一次打开时,被一个加"7654 导航"的网站捆绑. 查看设置中启动页中,被设置如下:   解决   域名查看,阿里竟然为这样的网站搞隐私保护   尝试 安 ...

  8. Linux实战教学笔记25:自动化运维工具之ansible (一)

    第二十五节 ansible之文件的批量分发 标签(空格分隔): Linux实战教学笔记-陈思齐 ---本教学笔记是本人学习和工作生涯中的摘记整理而成,此为初稿(尚有诸多不完善之处),为原创作品,允许转 ...

  9. hog特征及其提取方法图示

    1 什么是hog特征 hog特征是histogram of gradient的缩写.我们观察图像时,信息更多来自目标边沿的突变.我们计算一块区域内的所有像素处的梯度信息,即突变的方向和大小,然后对36 ...

  10. Android中的几种多线程实现

    有以下几种方式: 1)Activity.runOnUiThread(Runnable) 2)View.post(Runnable) ;View.postDelay(Runnable , long) 3 ...