该算法被称为Z算法。
因此,我在谷歌上进行了搜索,但没有找到一个好的算法解释。请问您可以说明如何创建模式数组以及如何应用搜索过程吗?如果您能提供C++代码的话,那就更好了。
经过一段时间的学习,我终于明白了如何构建Z数组。我会在这里用简单的语言解释。
首先让我们了解什么是前缀:
例如:
在单词apple中,前缀可以是apple(或)appl(或)app(或)ap(或)a。
在单词banana中,前缀可以是banana(或)banan(或)bana(或)ban(或)ba(或)b。
解释:字符串T的任何子字符串S,如果从字符串T的开头匹配到字符串T的末尾或在末尾之前,则称为前缀。
希望您已经理解了这里的前缀是什么。
现在看看如何构建Z数组。
让我们以这个例子文本为例:a a b $ b a a b a a
索引:0 1 2 3 4 5 6 7 8 9
文本:a a b $ b a a b a a
Z值:x 1 0 0 0 3 1 0 2 1
注意:
a. 子字符串应该从第i个位置开始。
b. 子字符串应该是最长的同时也是一个前缀
从i(第0个索引)到末尾找到也是给定文本前缀的子字符串。
a a b $ b a a b a a => 长度为10的最长子字符串,也是文本的前缀。但这不能帮助模式匹配,所以我们将其设置为Z数组中的x。
从位置1开始查找直到末尾的最长子字符串,该子字符串也是给定文本的前缀。
这样的子字符串有:
a. "a" => 文本"a a b $ b a a b a a"的前缀,长度为1。
b. "a b" => 不是前缀
c. "a b $" => 不是前缀
d. "a b $ b" => 不是前缀
e. "a b $ b a" => 不是前缀
等等...
这里唯一的最长子字符串也是一个前缀是"a",它的长度为1。它被存储在Z数组中。
子字符串如下:
a. "b" => 不是前缀
b. "b $" => 不是前缀
c. "b $ b" => 不是前缀
等等...
这里没有子字符串也是文本T的前缀。因此,我们在Z数组的索引2处存储零。
在索引5处:> 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}
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.
您可以在这里找到详细的解释和实现