知识点 - KMP与Z函数

知识点 - KMP

解决问题类型:

前缀函数

查找子串

每个前缀的出现次数

本质不同子串的个数O(n^2)

字符串压缩:找到t使得s可以被多个t重复出现得到

前缀自动机

Z函数

查找子串

本质不同子串的个数O(n^2)

字符串压缩

定义与代码:

前缀函数 π \pi π(prefix function): π [ i ] \pi[i] π[i]代表子串 s [ 0 … i ] s[0 \dots i] s[0i]与其后缀相等的最长真前缀(proper prefix,即不包含本身的前缀)。
π [ i ] = max ⁡ k = 0 … i { k : s [ 0 … k − 1 ] = s [ i − ( k − 1 ) … i ] } \pi[i] = \max_ {k = 0 \dots i} \{k : s[0 \dots k-1] = s[i-(k-1) \dots i] \} π[i]=k=0imax{k:s[0k1]=s[i(k1)i]}
“aabaaab” - [ 0 , 1 , 0 , 1 , 2 , 2 , 3 ] [0, 1, 0, 1, 2, 2, 3] [0,1,0,1,2,2,3].

O ( n ) O(n) O(n),在线

vector<int> prefix_function(string s) {
    int n = (int)s.length();
    vector<int> pi(n);
    for (int i = 1; i < n; i++) {
        int j = pi[i-1];
        while (j > 0 && s[i] != s[j])
            j = pi[j-1];
        if (s[i] == s[j])
            j++;
        pi[i] = j;
    }
    return pi;
}

Z函数: z [ i ] z[i] z[i]代表串s 和其后缀 s [ i . . . n − 1 ] s[i...n-1] s[i...n1] 的LCP, 定义z[0]=0

“abacaba” - [ 0 , 0 , 1 , 0 , 3 , 0 , 1 ] [0, 0, 1, 0, 3, 0, 1] [0,0,1,0,3,0,1]

O ( n ) O(n) O(n),

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] = min (r - i + 1, z[i - l]);
		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;
}

例题

prefix

Z

hdu#5 签到 string matching

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Best KeyBoard

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值