字符串

KMP

#include <cstdio>
#include <cstring>
#define R register
const int MAXN=1000007;
int l,l1;
char s[MAXN],s1[MAXN];
int fail[MAXN];
inline void get_next()
{
    int p=0;
    for(R int i=2;i<=l;++i)
    {
        while(p>0&&s[i]!=s[p+1]) p=fail[p];
        if(s[i]==s[p+1]) p++;
        fail[i]=p;
    }
}

inline void kmp()
{
    int p=0;
    for(R int i=1;i<=l1;++i)
    {
        while(p>0&&s[p+1]!=s1[i]) p=fail[p];
        if(s[p+1]==s1[i]) p++;
        if(p==l)
        {
            printf("%d\n",i-l+1);
            p=fail[p];
        }
    }
}

int main()
{
    scanf("%s%s",s1+1,s+1);
    l=strlen(s+1);
    l1=strlen(s1+1);
    get_next();
    kmp();
    for(int i=1;i<=l;++i)
        printf("%d ",fail[i]);
    return 0;
}

字典树,trie树

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

int n;
struct node {
    int next[27];
    bool w;
} a[300000];
int tot;
bool flag[300000];

void build(char *b) {
    int p=0,len=strlen(b);
    for(int i=0; i<len; ++i) {
        int x=b[i]-'a';
        if(!a[p].next[x]) {
            a[p].next[x]=++tot;
        }
        p=a[p].next[x];
    }
    flag[p]=1;
}

void find(char *b) {
    int p=0,len=strlen(b);
    for(int i=0; i<len; ++i) {
        int x=b[i]-'a';
        if(!a[p].next[x]) {
            printf("NO\n");
            return;
        }
        p=a[p].next[x];
    }
    if(flag[p]) printf("YES\n");
    else printf("NO\n");
}

int main() {
    int n,m;
    char s[100];
    scanf("%d",&n);
    for(int i=1; i<=n; ++i)
        scanf("%s",s),build(s);
    scanf("%d",&m);
    while(m--)
        scanf("%s",s),find(s);
    return 0;
}

马拉车

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=11000007;
char s[maxn],S[maxn];
int p[maxn<<1];
int main()
{
    scanf("%s",s);
    S[0]='@';S[1]='#';
    int l=1,i=-1;
    while(s[++i]!='\0')
        S[++l]=s[i],S[++l]='#';
    int mx=0,id=0,ans=0;
    for(int i=1;i<=l;++i)
    {
        if(mx>i) p[i]=min(p[id*2-i],mx-i);//id*2-i即i-k
        else p[i]=1;
        while(S[i+p[i]]==S[i-p[i]]) p[i]++;
        if(mx<i+p[i]-1) mx=i+p[i]-1,id=i;
        ans=max(p[i]-1,ans);
    }
    printf("%d",ans);
    return 0;
}

AC自动机

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int N=2000100;
struct Tree{
    int fail,end; 
    int vis[27]; 
}e[N]; 

int cnt,n;
char s[N];

inline int read() {
    int n=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    while (ch<='9'&&ch>='0') {n=n*10+ch-'0';ch=getchar();}
    return n*f;
}

inline void insert(char *s) {
    int n=strlen(s);
    int now=0;
    for(int i=0;i<n;++i) {
        int tmp=s[i]-'a';
        if(!e[now].vis[tmp]) e[now].vis[tmp]=++cnt;
        now=e[now].vis[tmp];
    }
    e[now].end++;
} 

inline void build() {
    queue<int> q;
    for(int i=0;i<26;++i)
        if(e[0].vis[i])
            q.push(e[0].vis[i]),e[e[0].vis[i]].fail=0;
    while(!q.empty()) {
        int u=q.front();
        q.pop();
        for(int i=0;i<26;++i)
            if(e[u].vis[i]) {
                e[e[u].vis[i]].fail=e[e[u].fail].vis[i];
                q.push(e[u].vis[i]);    
            }
            else e[u].vis[i]=e[e[u].fail].vis[i];
    }
}

inline void query(char *s) {
    int l=strlen(s);
    int now=0,ans=0; 
    for(int i=0;i<l;++i) {
        int now=e[now].vis[s[i]-'a'];
        for(int t=now;t&&e[t].end!=-1;t=e[t].fail) {
            ans+=e[t].end;
            e[t].end=-1; 
        } 
    }
    printf("%d\n",ans); 
} 

int main() {
    n=read();
    for(int i=1;i<=n;++i) cin>>s,insert(s);
    build();
    cin>>s;
    query(s); 
    return 0; 
}
全部评论

相关推荐

小红书 后端选手 n*16*1.18+签字费期权
点赞 评论 收藏
分享
11-01 08:48
门头沟学院 C++
伤心的候选人在吵架:佬你不要的,能不能拿户口本证明过户给我。。球球了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务