4天后,我正在阅读字符串和一些算法进行模式匹配,为此我得到了KMP搜索算法,这很好,但我还得到了另一种字符串匹配方法,与空间中的KMP相同和时间的复杂性,但有一个简单的解决方案。
算法是Z算法。
因此,我搜索谷歌,但我没有找到一个很好的解释算法。你能解释一下如何创建模式数组以及如何应用搜索过程吗?如果您将用c ++提供代码,那将是很好的。
答案 0 :(得分:7)
很长一段时间后,我明白了如何构建Z阵列。我会用简单的话来解释。
让我们先了解什么是前缀:
示例:
在word apple中,前缀可以是apple(或)appl(或)app(或)ap(或)a。
在单词banana中,前缀可以是banana(或)banan(或)bana(或)ban(或)ba(或)b。
说明:从字符串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应该是最大长度,也是前缀
从i(第0个索引)到结束查找子字符串,这也是给定文本的前缀。
a a b b b a a b a a =>长度为10的是最长的子串,它也是文本的前缀。但这对模式匹配没有帮助,所以我们把它作为Z数组中的x。
查找从位置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数组中。
子字符串是:
一个。 “b”=>不是前缀
湾“b $”=>不是前缀
℃。 “b $ b”=>不是前缀
等......
这里没有子串,它也是文本T的前缀。所以我们在Z数组的索引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