-
KMP(Lead-in)
KMP算法全称Knuth-Morris-Pratt算法,可以在的时间复杂度下进行在长度为的字符串(文本串)中查找另一个长度为的字符串(模式串)出现的所有位置,同时也能在的时间复杂度下查找一个长度为的字符串中,前缀和后缀相同的最大长度。
首先思考一下,如何暴力地在一个字符串中查找另一字符串出现的所有位置,很快可以找到这样一种思路:枚举文本串中所有位置作为模式串的首个字符,然后向后遍历判断这个字符之后是否存在模式串,实现代码如下:
#include <iostream>
using namespace std;
int main() {
ios::sync_with_stdio(false);
string a, b;
int ans = 0;
cin >> a >> b;
int la = a.length(), lb = b.length();
for (int i = 0; i < la; ++i) {
if (a[i] == b[0]) {
for (int j = 0; j < lb; ++j) {
if (a[i + j] != b[j]) break;
if (j == lb - 1) ++ans;
}
}
}
cout << ans << endl;
return 0;
}
-
KMP(查找)
显然,此时程序的复杂度是的,我们需要对时间复杂度进行优化。
我们可以发现,在上一个代码中,当我们枚举一个字符时,这个字符很可能在我们枚举的时候就被枚举过了,所以我们要对这一部分操作进行精简。
我们引入一个数组,表示在模式串的区间中,前缀和后缀相等的最大长度。
假设以文本串的位置为模式串的起始位置进行匹配,匹配到文本串的位置(模式串的位置)出现了失配的情况,按暴力算法我们会以文本串的位置为模式串的起始位置继续匹配模式串。
然而,我们发现,当出现失配的时候,我们已经有区间内的文本串等于区间内的模式串。
由数组的定义易得在模式串中,有区间与区间相等
所以模式串的也等于文本串的区间。
所以这时我们可以视为我们以文本串的为起始位置进行匹配,正在匹配文本串中位置的字符是否与模式串中位置的字符相等。
所以,综上所述,我们在匹配字符串时,假设我们在匹配模式串中位置上的字符时出现失配的情况,我们只需让然后继续与文本串内的字符继续向后比对,如果再次失配就再次跳,当指向模式串最后一位的下一位时就找到了文本串中的一个模式串。
易得代码实现如下:
for (int j = 0, i = 0; i < len1; ++i) {
while (j && (s1[i] != s2[j])) j = nxt[j];
if (s1[i] == s2[j]) ++j;
if (j == len2) cout << i - len2 + 1 << endl;
}
-
KMP(求nxt)
接下来我们就要求数组,假设我们已经求出来了,然后我接下来要求,那么我们只需要确认和是否相等,如果不相等就跳到下一个,发现基本的思想就是自己跟自己匹配,那么易得代码如下所示(i和j要错开要不然一直是相同的)
for (int j = 0, i = 1; i < len2; ++i) {
while (j && (s2[i] != s2[j])) j = nxt[j];
if (s2[i] == s2[j]) nxt[i + 1] = ++j;
else nxt[i + 1] = 0;
}
-
KMP(时间复杂度)
我们可以发现KMP算法只需要对模式串和文本串各遍历一遍即可(少数的跳操作基本上可以忽略)。
我们优化的思路是尽可能地运用我们已经得出的结果,即尽量从已经得出的状态转移到一个新状态。
-
Manacher(Lead-in)
Manacher算法可以在的时间复杂度下解决寻找一个字符串内最长回文字符串的问题,这个问题用暴力很好解决。
枚举回文串的奇偶性,若是奇数则枚举中心字符向左右两边扩展,若是偶数就枚举最中心偏左的字符向左右两边扩展。
这个算法分奇偶性,显然并不美观,那我们可以将偶数时也枚举中心,但是枚举的是两个字符间的空格。
然后我们可以将原字符串的空格都用'#'字符代替,然后字符串的左右两头用不同的字符代替。
举个例子,若原字符串是"Kazdale",则转换后的字符串则为“#K#a#z#d#a#l#e#.”,我们设若枚举为中心,则中心加上回文串的右半边的长度为,例如字符串aba(转换后为#a#b#a#.),它的就等于4,易证字符串转换后求出的减即为以为中心时的回文串长度。
-
Manacher
暴力算法的时间复杂度为,我们需要进行优化,
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】