0
点赞
收藏
分享

微信扫一扫

AC自动机

钎探穗 2022-02-04 阅读 49

AC自动机

没用的AC自动机
问题链接

#include <iostream>
#include <cstring>


using namespace std;
const int N = 1e6 + 5, MM = 10501;
char Sin[N], mstr[151][71];
int DictionaryTree[MM][28], ide, fail[MM];
int W[151], cnt[MM];
void ins(char *str, int n) {
    int now(0);
    for ( ; *str; ++ str) {
        if (!DictionaryTree[now][*str - 'a']) 
            DictionaryTree[now][*str - 'a'] = ++ ide,
            DictionaryTree[ide][27] = now;
        now = DictionaryTree[now][*str - 'a'];
    }
    W[n] = now;
}
int Q[MM], NowIcpy;
void DictionaryTreeClear(int *now = DictionaryTree[0]) {
    for (int i(0); i < 26; ++ i) if (now[i]) NowIcpy = now[i], now[i] = 0, DictionaryTreeClear(DictionaryTree[NowIcpy]);
}
void ACautomation(char *str, int n, int iend) {
    int now(0), maxn(0);
    memset(cnt, 0, 4 * W[n] + 4);
    for ( ; *str; ++ str) 
        ++ cnt[now = DictionaryTree[now][*str - 'a']];
    for (int i = iend; i; -- i) cnt[fail[Q[i]]] += cnt[Q[i]];
    for (int i = n; i; -- i) maxn = max(cnt[W[i]], maxn);
    printf("%d\n", maxn);
    for (int i = 1; i <= n; ++ i) 
        if (maxn == cnt[W[i]]) 
            puts(mstr[i]);
    DictionaryTreeClear();
    memset(fail, 0, 4 * ide + 4), ide = 0;
}
void build(char *str, int n, int iend = 0, int top = 0) {
    for (int i(0); i < 26; ++ i) if (DictionaryTree[0][i]) Q[++ iend] = DictionaryTree[0][i];
    int* now;
    while (top ^ iend) {
        now = DictionaryTree[Q[++ top]];
        for (char i(0); i < 26; ++ i) {
            if (now[i]) fail[now[i]] = DictionaryTree[fail[Q[top]]][i], Q[++ iend] = now[i];
            else now[i] = DictionaryTree[fail[Q[top]]][i];
        }
    }
    ACautomation(Sin, n, iend);
}

signed main() {
    int n;
    while (scanf("%d", &n), n) {
        for (int i = 1; i <= n; ++ i) scanf("%s", mstr[i]), ins(mstr[i], i);
        scanf("%s", Sin);
        build(Sin, n);
    }
    return 0;
}
举报

相关推荐

0 条评论