Z Function (Ex. KMP)
约定:字符串下标以
对于个长度为
国外一般将计算该数组的算法称为 Z Algorithm,而国内则称其为 扩展 KMP。
这篇文章介绍在
样例¶
下面若干样例展示了对于不同字符串的 Z 函数:
z(\mathtt{aaaaa}) = [0, 4, 3, 2, 1] z(\mathtt{aaabaab}) = [0, 2, 1, 0, 2, 1, 0] z(\mathtt{abacaba}) = [0, 0, 1, 0, 3, 0, 1]
朴素算法¶
Z 函数的朴素算法复杂度为
vector<int> z_function_trivial(string s) {
int n = (int)s.length();
vector<int> z(n);
for (int i = 1; i < n; ++i)
while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i];
return z;
}
线性算法¶
如同大多数字符串主题所介绍的算法,其关键在于,运用自动机的思想寻找限制条件下的状态转移函数,使得可以借助之前的状态来加速计算新的状态。
在该算法中,我们从
对于
算法的过程中我们维护右端点最靠右的匹配段。为了方便,记作
在计算
- 如果
i\le r [l,r] s[i,r] = s[i-l,r-l] z[i]\ge \min(z[i-l],r-i+1) - 若
z[i-l] < r-i+1 z[i] = z[i-l] - 否则
z[i-l]\ge r-i+1 z[i] = r-i+1 z[i]
- 若
- 如果
i>r s[i] z[i] - 在求出
z[i] z[i]>r [l,r] l=i, r=i+z[i]-1
可以访问 这个网站 来看 Z 函数的模拟过程。
实现¶
vector<int> z_function(string s) {
int n = (int)s.length();
vector<int> z(n);
for (int i = 1, l = 0, r = 0; i < n; ++i) {
if (i <= r && z[i - l] < r - i + 1) {
z[i] = z[i - l];
} else {
z[i] = max(0, r - i + 1);
while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i];
}
if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1;
}
return z;
}
复杂度分析¶
对于内层 while
循环,每次执行都会使得
对于外层循环,只有一遍线性遍历。
总复杂度为
应用¶
我们现在来考虑在若干具体情况下 Z 函数的应用。
这些应用在很大程度上同 前缀函数 的应用类似。
匹配所有子串¶
为了避免混淆,我们将
为了解决该问题,我们构造一个新的字符串
首先计算
其时间复杂度(同时也是其空间复杂度)为
本质不同子串数¶
给定一个长度为
考虑计算增量,即在知道当前
令
设串
所以,将字符
算法时间复杂度为
值得注意的是,我们可以用同样的方法在
字符串整周期¶
给定一个长度为
考虑计算
该事实的证明同应用 前缀函数 的证明一样。
练习题目¶
- CF126B Password
- UVA # 455 Periodic Strings
- UVA # 11022 String Factoring
- UVa 11475 - Extend to Palindrome
- LA 6439 - Pasti Pas!
- Codechef - Chef and Strings
- Codeforces - Prefixes and Suffixes
本页面主要译自博文 Z-функция строки и её вычисление 与其英文翻译版 Z-function and its calculation。其中俄文版版权协议为 Public Domain + Leave a Link;英文版版权协议为 CC-BY-SA 4.0。
buildLast update and/or translate time of this article,Check the history
editFound smelly bugs? Translation outdated? Wanna contribute with us? Edit this Page on Github
peopleContributor of this article LeoJacob, Marcythm, minghu6
translateTranslator of this article Visit the original article!
copyrightThe article is available under CC BY-SA 4.0 & SATA ; additional terms may apply.