字符串简介
kmp算法,扩展kmp,manacher
kmp算法视频讲解
Next数组视频讲解
manacher视频讲解
kmp
扩展kmp
manacher
个人认为hash和字典树还是比kmp容易理解的,ac自动机的话先需要有kmp和字典树的基础。
hash
字典树
ac自动机
提供一种我认为比较好用的模板
//求解原串中包含多少模式串,模式串可以互相覆盖,不能覆盖的稍微修改一下即可
char ori[N*100], pat[N];//ori为原串,pat为模式串
int Next[N];
void get_next(char *pat)
{
int i = 0, j = -1;
Next[0] = -1;
while(pat[i])
{
if(j == -1 || pat[i] == pat[j]) Next[++i] = ++j;
else j = Next[j];
}
}
//void get_next(char *pat) //对next数组的优化
//{
// int i = 0, j = -1;
// Next[0] = -1;
// while(pat[i])
// {
// if(j == -1 || pat[i] == pat[j])
// {
// ++i, ++j;
// if(pat[i] != pat[j]) Next[i] = j;
// else Next[i] = Next[j];
// }
// else j = Next[j];
// }
//}
int kmp(char *ori, char *pat)
{
get_next(pat);
int ans = 0;
int i = 0, j = 0;
while(ori[i])
{
if(j == -1 || ori[i] == pat[j]) ++i, ++j;
else j = Next[j];
if(j != -1 && !pat[j]) ans++, j = Next[j];//模式串不能互相覆盖,改j=0即可
}
return ans;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%s%s", pat, ori);
int ans = kmp(ori, pat);
printf("%d\n", ans);
}
return 0;
}
int P[N];
char s[N], str[N];
void manacher()
{
int l = 0;
s[l++] = '$';
for(int i = 0; str[i]; ++i)
s[l++] = '#', s[l++] = str[i];
s[l++] = '#';
s[l] = '\0';
int r = 0, c = 0;
for(int i = 1; i < l; ++i)
{
int &p = P[i]; //&是c++中的引用
p = r>i?min(P[2*c-i], r-i):1;
while(s[i+p]==s[i-p]) p++;
if(i+p > r) r = i+p, c = i;
}
}