z算法的实现

时间:2015-08-06 20:27:50

标签: string algorithm data-structures knuth-morris-pratt

4天后,我正在阅读字符串和一些算法进行模式匹配,为此我得到了KMP搜索算法,这很好,但我还得到了另一种字符串匹配方法,与空间中的KMP相同和时间的复杂性,但有一个简单的解决方案。

算法是Z算法。

因此,我搜索谷歌,但我没有找到一个很好的解释算法。你能解释一下如何创建模式数组以及如何应用搜索过程吗?如果您将用c ++提供代码,那将是很好的。

2 个答案:

答案 0 :(得分:7)

很长一段时间后,我明白了如何构建Z阵列。我会用简单的话来解释。

让我们先了解什么是前缀:

示例:

  1. 在word apple中,前缀可以是apple(或)appl(或)app(或)ap(或)a。

  2. 在单词banana中,前缀可以是banana(或)banan(或)bana(或)ban(或)ba(或)b。

  3. 说明:从字符串T的开头到字符串T的结尾或结尾之前匹配的字符串T的任何子字符串S都被称为前缀。

    希望你明白这里的前缀是什么。

    让我们看看如何构建Z数组。

    让我们以这个示例文本为例:a a b b b a a b a a

    指数:0 1 2 3 4 5 6 7 8 9

    文字:a b b b a a b a a

    Z值:x 1 0 0 0 3 1 0 2 1

    注意:

    一个。子串应该从第i个位置开始。

    湾substring应该是最大长度,也是前缀

    1. 在索引0:
    2. 从i(第0个索引)到结束查找子字符串,这也是给定文本的前缀。

      a a b b b a a b a a =>长度为10的是最长的子串,它也是文本的前缀。但这对模式匹配没有帮助,所以我们把它作为Z数组中的x。

      1. 索引1:
      2. 查找从位置1到结尾的最长子字符串,它也是文本的前缀。

        这样的子串是:

        一个。 “a”=>文本的前缀“a a b b b a a b a a”,长度为1。

        湾“a b”=>不是前缀

        ℃。 “a b $”=>不是前缀

        d。 “a b $ b”=>不是前缀

        即“a b $ b a”=>不是前缀

        等......

        这里唯一最长的子串也是前缀是“a”,长度是1.它存储在Z数组中。

        1. 在索引2:
        2. 子字符串是:

          一个。 “b”=>不是前缀

          湾“b $”=>不是前缀

          ℃。 “b $ b”=>不是前缀

          等......

          这里没有子串,它也是文本T的前缀。所以我们在Z数组的索引2处存储零。

          1. 在索引5:
          2. 子串是:

            一个。 “a”=>文本的前缀“a a b b b a a b a a”,长度为1。

            湾“a a”=>文本的前缀“a a b b b a a b a a”,长度为2。

            ℃。 “a a b”=>文本的前缀“a a b b b a a b a a”,长度为3。

            d。 “a a b a”=>不是前缀

            等......

            这里最长的子串也是文本T的前缀是长度为3的“a a b”。所以我们在Z数组中将索引5存储为3。

            最后,如果Z数组中的任何值与模式的长度相同,那么该模式将出现在文本T中。

答案 1 :(得分:1)

在Z-algo中,我们构造了一个Z阵列。

什么是Z阵列? 对于字符串str [0..n-1],Z数组与字符串的长度相同。 Z数组的元素Z [i]存储从str [i]开始的最长子串的长度,其也是str [0..n-1]的前缀。 Z数组的第一个条目意味着更少,因为完整的字符串始终是它自己的前缀。

> Example: Index            0   1   2   3   4   5   6   7   8   9  10  11
> Text                      a   a   b   c   a   a   b   x   a   a   a   z   
> values         X          1   0   0   3   1   0   0   2   2   1   0  More
> Examples: str  = "aaaaaa" Z[]  = {x, 5, 4, 3, 2, 1}
> 
> str = "aabaacd" Z[] = {x, 1, 0, 2, 1, 0, 0}
> 
> str = "abababab" Z[] = {x, 0, 6, 0, 4, 0, 2, 0}

这个想法是连接模式和文本,并创建一个字符串“P $ T”,其中P是模式,$是一个特殊字符不应该出现在模式和文本中,而T是文本。为连接字符串构建Z数组。在Z数组中,如果任何点的Z值等于模式长度,则在该点存在模式。

Example:
Pattern P = "aab",  Text T = "baabaa"

The concatenated string is = "aab$baabaa"

Z array for above concatenated string is {x, 1, 0, 0, 0, 
                                          3, 1, 0, 2, 1}.
Since length of pattern is 3, the value 3 in Z array 
indicates presence of pattern. 

您可以找到的详细说明和实施 here