KMP
烤馍片是一种算法,这种算法我忘了就学,学了就忘,所以这里再写一遍加深印象(
KMP 这个东西呢它可以在 的时间复杂度内完成字符串的匹配,虽然但是我用字符串哈希我做匹配不也一个道理吗?KMP 可以与处理出来一个叫 的数组(也可以叫 ),可以完成很多很厉害的东西。
下面我们先来了解一下 是干嘛的:定义函数 为字符串长度为 的前缀 的 最长的与字符串本身不同的 后缀 与 前缀 相同的长度。这样说好像不太容易理解也不太严谨,我们炒个例子罢,比如字符串
s: a b a b a b c
,什么意思嘞,就是说 a b a b a
中,前三个 a b a
和后三个 a b a
是一样的。那么对于 呢?是 。
可以这样求:首先 ,显然易见,下面我们假设已经求出来了 ,考虑到了 ,我们充分利用一下之前得到的信息:
蓝色部分代表相同的,根据定义,左边的红色部分代表 右边的红的代表 ,如果 (两个红的相等),是不是就说明一点:?
那万一它们不相同呢?那我们退而求其次,像这样
如果两个橙色的相等(),那么 。推广开来我们可以这样搞:对于求 ,定义一个指针 , 一开始等于 。如果 ,说明这个行,。否则 。原因的话相信看看图就不难理解了 qwq
求出来了 ,它有什么用呢?它可以搞字符串匹配。以这道题模板题 link 为例。我们先求出来了 的 。我们来手玩一个小样例
ABADBC
ABAC
首先它们登登登匹配到第三位,到了第四位发现 D 和 C 不一样,那么怎么办,从头再来?我们发现我们知道了 前三位是 ABA, 的前三位也是 ABA,我们肯定不会这样匹配
ABA
ABA
因为这肯定不行,聪明的我们会想到这样匹配
ABA
ABA
深究一下其中的原因,因为这个 A 既是 ABA 的后缀,也是 ABA 的前缀……等等,?这个相信是不难领会的,还可以举个例子
ABABAD
ABABAB
匹配到第五位失配了,但是 前五位和 前五位都是 ABABA
,我们光来匹配这几个已知的,我们当然不会这样匹配
ABABA
ABABA
而是
ABABA
ABABA
因为这样肯定能匹配上一点。我们一定会从 开始,这相当于 前面都匹配过了。我们也容易理解为啥 要取最大——不取最大的话可能会漏。
这个算法就出来了:如果 是指向 的, 是指向 的,前 位与第 位匹配,现在我们考虑第 位与第 位。如果能匹配就匹配,不能匹配那么让 ,如果 ,那么就匹配成功,否则就再让 以此类推。
代码
//SIXIANG
#include <iostream>
#include <string>
#define MAXN 1000000
#define QWQ cout << "QWQ" << endl;
using namespace std;
int fail[MAXN + 10];
void init() {
string s1, s2;
cin >> s1 >> s2;
s1 = " " + s1, s2 = " " + s2;
fail[1] = 0;
for(int p = 2; p < s2.size(); p++) {
int i = fail[p - 1];
while(s2[i + 1] != s2[p] && i) i = fail[i];
if(s2[i + 1] == s2[p]) fail[p] = i + 1;
else fail[p] = i;
}
int i = 0, end = s2.size() - 1;
for(int p = 1; p < s1.size(); p++) {
while(s2[i + 1] != s1[p] && i) i = fail[i];
if(s2[i + 1] == s1[p])
i++;
if(i == end) cout << p - end + 1 << endl;
}
for(int p = 1; p < s2.size(); p++)
cout << fail[p] << ' ';
}
int main() {
init();
}
可是很显然我随手搓一个字符串哈希,比这个起码要好理解很多,效率也是 的呀。这里面的 有一个很厉害的作用。比如说有一道题根字符串的循环节有关系,我们就可以用 。比如说这道题 link。
先给出结论,答案是 。为啥捏?
相信这张图相当明白了()
那么别的拓展也能轻而易举的得到,如果 ,那么这个字符串一定能由前 个字符重复 次形成。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2020-07-07 欢迎来到 SIXIANG 的 blog~