Z-algorithm史上最详细讲解

Z-Algorithm详解

0.前言

给你一个文本串 t t t和一个模式串 p p p,让你寻找 p p p t t t中出现的所有位置。

例如, t = " a b a c a b a b a c " t="abacababac" t="abacababac" p = " a b a " p="aba" p="aba",那么 p p p t t t中出现了 3 3 3次,起始位置分别是 1 1 1 5 5 5 7 7 7

很显然可以想到 O ( ∣ t ∣ ∗ ∣ p ∣ ) O(|t|*|p|) O(tp)的暴力算法,但是如果 t t t p p p的长度都是 1 0 5 10^5 105级别的就会超时,我们需要更高效的方法,这里我给大家讲一下 Z Z Z算法。

1.一些函数的定义

我们定义 z i ( s ) z_i(s) zi(s)为对于所有的 2 ≤ i ≤ ∣ s ∣ 2 \leq i \leq |s| 2is,以 i i i开头的子串和 s s s的最长公共前缀的长度

如:

s = " a b a " s="aba" s="aba",那么 z 3 ( s ) = 1 z_3(s)=1 z3(s)=1(以 3 3 3为起始位置,能够匹配 s s s长度为 1 1 1的前缀 " a " "a" "a",但匹配不了长度为 2 2 2的前缀 " a b " "ab" "ab")。

s = " a b c a b c a b " s="abcabcab" s="abcabcab",那么 z 4 ( s ) = 5 z_4(s)=5 z4(s)=5

s = " a b a c a b a b a c a " s="abacababaca" s="abacababaca",那么 z 5 ( s ) = 3 , z 7 ( s ) = 5 z_5(s)=3, z_7(s)=5 z5(s)=3,z7(s)=5

2.如果已知 z i z_i zi的值如何求出答案

我们将 p p p粘在 s s s的前面,中间用一个字符(如下划线)隔开,可以得到一个字符串 s s s。我们假设我们已经知道了所有 z i ( s ) z_i(s) zi(s)的值,那么怎么求出答案呢。

我们可以扫描 s s s串中从 ∣ p ∣ + 2 |p|+2

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值