字符串专题

字符串简介
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;
  
    }
}

你可能感兴趣的:(字符串)