Z 函数
参考资料
简介
对于长度为 的字符串 ,定义 Z 函数(Z-function) 为 与 的最长公共前缀(LCP)的长度,特别地 。国内通常称计算该数组的算法为 扩展 KMP(exKMP)。
维护当前右端点最靠右的匹配段 ,则 是 的前缀。计算 时:若 ,则 ;否则从头暴力扩展。每次扩展都使 至少右移 1,总时间复杂度为 。
实现
#include <bits/stdc++.h>
using namespace std;
const int N=500005;
int z[N];
void z_func(string s)
{
int n=s.size();
z[0]=0;
for(int i=1,l=0,r=0;i<n;i++)
{
z[i]=i<=r?min(z[i-l],r-i+1):0;
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;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s;
cin>>s;
z_func(s);
int n=s.size();
for(int i=0;i<n;i++)cout<<z[i]<<' ';
return 0;
}
应用
模式匹配:求模式串 在文本 中的所有出现位置。取分隔符 #(不在两串中),对 求 Z 函数,凡 的位置都对应 中的一次匹配。
最小循环节:枚举 ,若 ,则 的前 个字符构成一个周期;最小的这样的 即最小循环节长度。若还满足 ,则 由该循环节整数次重复而成。