字符串

P3375 【模板】KMP 字符串匹配

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

const int N = 1e6 + 10;

char s[N], t[N];
int n, m;
int bd[N];

int main(){

    scanf("%s%s", (s+1), (t+1));

    n = strlen(s+1);
    m = strlen(t+1);

    int j = 0;
    bd[1] = 0;
    for(int i = 2; i <= m; i++){
        while(j && t[j+1] != t[i]){
            j = bd[j];
        }
        if(t[j+1] == t[i]){
            j++;
        }
        bd[i] = j;
    }

    j = 0;
    for(int i = 1; i <= n; i++){
        while(j && t[j+1] != s[i]){
            j = bd[j];
        }
        if(t[j+1] == s[i]){
            j++;
        }
        if(j == m){
            printf("%d\n", i-m+1);
            j = bd[j];
        }
    }

    for(int i = 1; i <= m; i++){
        printf("%d ", bd[i]);
    }
    puts("");

    return 0;
}

142. 前缀统计

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

const int N = 1e5 + 10, M = 1e6 + 10;

int n, m;
char str[M];
struct node{
    int num;
    int son[26];
}tr[M];
int tcnt = 1;

void insert(char *s){
    int len = strlen(s+1);
    int p = 1;
    for(int i = 1; i <= len; i++){
        int j = s[i] - 'a';
        if(!tr[p].son[j]){
            tr[p].son[j] = ++tcnt;
        }
        p = tr[p].son[j];
    }
    tr[p].num++;
}

int query(char *s){
    int len = strlen(s+1);
    int p = 1;
    int tans = 0;
    for(int i = 1; i <= len; i++){
        int j = s[i] - 'a';
        if(!tr[p].son[j]){
            return tans;
        }
        p = tr[p].son[j];
        tans += tr[p].num;
    }
    return tans;
}

int main(){

    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++){
        scanf("%s", str+1);
        insert(str);
    }

    for(int i = 1; i <= m; i++){
        scanf("%s", str+1);
        printf("%d\n", query(str));
    }

    return 0;
}

P3796 【模板】AC 自动机(加强版)

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>

using namespace std;

const int N = 11000;

int n;
char s[160][80], t[1000010];
int cnt[160];
int ans;

int son[N][26], num[N], fal[N], tcnt;

int New(){
    tcnt++;
    for(int i = 0; i < 26; i++){
        son[tcnt][i] = 0;
    }
    num[tcnt] = 0;
    fal[tcnt] = 0;
    return tcnt;
}

void insert(int x){
    int len = strlen(s[x]+1);
    int p = 1;
    for(int i = 1; i <= len; i++){
        int j = s[x][i] - 'a';
        if(!son[p][j]){
            son[p][j] = New();
        }
        p = son[p][j];
    }
    num[p] = x;
}

queue<int> q;
void build(){
    for(int i = 0; i < 26; i++){
        son[0][i] = 1;
    }
    fal[1] = 0;
    q.push(1);
    while(!q.empty()){
        int x = q.front();
        q.pop();
        for(int i = 0; i < 26; i++){
            if(son[x][i]){
                fal[son[x][i]] = son[fal[x]][i];
                q.push(son[x][i]);
            }else{
                son[x][i] = son[fal[x]][i];
            }
        }
    }
}

void query(char *str){
    int len = strlen(str+1);
    int p = 1;
    for(int i = 1; i <= len; i++){
        int j = str[i] - 'a';
        p = son[p][j];
        for(int k = p; k; k = fal[k]){
            cnt[num[k]]++;
        }
    }
}

int main(){

    while(scanf("%d", &n), n){
        tcnt = 0;
        New();
        for(int i = 1; i <= n; i++){
            cnt[i] = 0;
            scanf("%s", (s[i]+1));
            insert(i);
        }
        build();
        scanf("%s", (t+1));
        query(t);
        ans = 0;
        for(int i = 1; i <= n; i++){
            ans = max(ans, cnt[i]);
        }
        printf("%d\n", ans);
        for(int i = 1; i <= n; i++){
            if(ans == cnt[i]){
                printf("%s\n", (s[i]+1));
            }
        }
    }

    return 0;
}

P5357 【模板】AC 自动机(二次加强版)

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<vector>

using namespace std;

const int N = 2e5 + 10, M = 2e6 + 10;

int n;
char s[N], t[M];
int cnt[N];
int bl[M];
int son[M][26], fal[M], tcnt = 1;

vector<int> g[M];

void insert(int x){
    int len = strlen(s+1);
    int p = 1;
    for(int i = 1; i <= len; i++){
        int j = s[i] - 'a';
        if(!son[p][j]){
            son[p][j] = ++tcnt;
        }
        p = son[p][j];
    }
    bl[x] = p;
}

queue<int> q;
void build(){
    for(int i = 0; i < 26; i++){
        son[0][i] = 1;
    }
    fal[1] = 0;
    q.push(1);
    while(!q.empty()){
        int x = q.front();
        q.pop();
        for(int i = 0; i < 26; i++){
            if(son[x][i]){
                fal[son[x][i]] = son[fal[x]][i];
                g[son[fal[x]][i]].push_back(son[x][i]);
                q.push(son[x][i]);
            }else{
                son[x][i] = son[fal[x]][i];
            }
        }
    }
}

void query(char *str){
    int len = strlen(str+1);
    int p = 1;
    for(int i = 1; i <= len; i++){
        int j = str[i] - 'a';
        p = son[p][j];
        cnt[p]++;
        // for(int k = p; k; k = fal[k]){
        //     cnt[k]++;
        // }
    }
}

void dfs(int x){
    for(int y : g[x]){
        dfs(y);
        cnt[x] += cnt[y];
    }
}

int main(){

    scanf("%d", &n);
    for(int i = 1; i <= n; i++){
        scanf("%s", (s+1));
        insert(i);
    }
    build();
    scanf("%s", (t+1));
    query(t);
    dfs(1);
    for(int i = 1; i <= n; i++){
        printf("%d\n", cnt[bl[i]]);
    }

    return 0;
}

KMP 求最小循环节(AcWing 141. 周期)

posted @ 2024-01-09 12:27  cjwen6  阅读(43)  评论(0)    收藏  举报