主要在这篇博客写下自己的总结,方便复习。
1.KMP算法
在了解KMP算法之前,信仰简单暴力出成绩的自己是只会暴力匹配的,在这里也说一下暴力匹配:
假设给出两个字符串 文本串 text 和 模式串 pattern ,需要判断字符串 pattern 是否是字符串 next 的子串, 只要枚举文本串的起始位置 i ,然后从该位逐位与模式串进行匹配, 每一位都匹配相同则成功 ,出现某位匹配不同,让文本串的起始位置变为 i+1, 然后从头匹配, 时间复杂度为两字符串长度乘积mn 。
而KMP算法的话可以把时间优化至两字符串的长度和m+n(字符串匹配过程m+Next数组赋值过程n),主要是当匹配失败时,将文本串的跳跃位置优化到一个更接近失配点的位置。
关于KMP算法的学习推荐:大神传送门:https://blog.csdn.net/v_JULY_v/article/details/7041827
以下时B站两个通俗易懂的学习视频以及对应模板:
(可以先看②next数组再看①kmp算法 )
①.KMP算法内容:https://www.bilibili.com/video/av11866460?from=search&seid=6372351953256652487
int KMP(char *t, char *p){
int i=0;
int j=0;
int lt=strlen(t);
int lp=strlen(p);
while(i < lt && j < lp){
//如果j=-1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++
if (j == -1 || s[i] == p[j])
{
i++;
j++;
}
else
{
//如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]
//next[j]即为j所对应的next值
j = next[j];
}
}
if (j == pLen)
return i - j;
else
return -1;
}
②.Next数组内容:https://www.bilibili.com/video/av16828557?from=search&seid=1458487256801175030
上面的next 数组的意义:当模式串中的某个字符跟文本串中的某个字符匹配失配时,模式串下一步应该跳到哪个位置。如模式串中在j 处的字符跟文本串在i 处的字符匹配失配时,下一步用 next [j] 处的字符继续跟文本串i 处的字符匹配,相当于模式串向右移动 j - next[j] 位。
关于next数组的应用:
-
周期性字符串 ⇔ n % ( n − next[n] ) == 0 && next[n] != 0 ,循环节长度是 n−next[n] 。
也可以理解为 n-next 的前缀为最小覆盖子串 。 -
模板:
void getNext(char *p, int *Next){
int i=0 , j=-1;
Next[i]=j;
int lp=strlen(p);
while(i<lp-1){
//p[j]表示前缀,p[i]表示后缀
if(j==-1||p[j]==p[i]){
++j,++i;
if(p[i]!=p[j])
Next[i]=j;
else
Next[i]=Next[j];
}
else j=Next[j];
}
}
以上,下面内容待续。
3.马拉车算法:https://blog.csdn.net/wu_tongtong/article/details/78984254
4.EKMP:https://www.cnblogs.com/dilthey/p/8620119.html
5.字符串Hash:https://www.cnblogs.com/Slager-Z/p/7807011.html
6.字典树:https://www.cnblogs.com/TheRoadToTheGold/p/6290732.html
7.KMP优化 —— 失配数组:https://www.cnblogs.com/lanqingzhou/p/8267975.html
8.AC自动机:https://www.cnblogs.com/wenzhixin/p/9448045.html