AC自动机是一种字符串匹配算法,可以用来在一个长文本串中查找多个模式串。C++中可以用Trie树和AC自动机实现,以下是AC自动机的实现代码:

  1. 定义Trie树结构体
const int MAXN = 100010;

struct Trie {
    int ch[MAXN][26], val[MAXN], sz;

    void insert(char* s, int v) {
        int u = 0, n = strlen(s);
        for (int i = 0; i < n; i++) {
            int c = s[i] - 'a';
            if (!ch[u][c]) ch[u][c] = ++sz;
            u = ch[u][c];
        }
        val[u] = v;
    }
};
  1. 构建AC自动机
void build_ac(Trie& tr) {
    queue<int> q;
    for (int i = 0; i < 26; i++) {
        if (tr.ch[0][i]) q.push(tr.ch[0][i]);
    }

    while (!q.empty()) {
        int u = q.front(); q.pop();
        for (int i = 0; i < 26; i++) {
            int v = tr.ch[u][i];
            if (v) {
                q.push(v);
                tr.val[v] |= tr.val[tr.ch[u][i]];
                tr.ch[u][i] = tr.ch[tr.ch[u][i]][i];
            } else {
                tr.ch[u][i] = tr.ch[tr.ch[u][0]][i];
            }
        }
    }
}
  1. AC自动机匹配
void match(Trie& tr, char* s) {
    int u = 0, n = strlen(s);
    for (int i = 0; i < n; i++) {
        int c = s[i] - 'a';
        u = tr.ch[u][c];
        if (tr.val[u]) {
            // 匹配到了模式串
        }
    }
}

完整代码如下:

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

const int MAXN = 100010;

struct Trie {
    int ch[MAXN][26], val[MAXN], sz;

    void insert(char* s, int v) {
        int u = 0, n = strlen(s);
        for (int i = 0; i < n; i++) {
            int c = s[i] - 'a';
            if (!ch[u][c]) ch[u][c] = ++sz;
            u = ch[u][c];
        }
        val[u] = v;
    }
};

void build_ac(Trie& tr) {
    queue<int> q;
    for (int i = 0; i < 26; i++) {
        if (tr.ch[0][i]) q.push(tr.ch[0][i]);
    }

    while (!q.empty()) {
        int u = q.front(); q.pop();
        for (int i = 0; i < 26; i++) {
            int v = tr.ch[u][i];
            if (v) {
                q.push(v);
                tr.val[v] |= tr.val[tr.ch[u][i]];
                tr.ch[u][i] = tr.ch[tr.ch[u][i]][i];
            } else {
                tr.ch[u][i] = tr.ch[tr.ch[u][0]][i];
            }
        }
    }
}

void match(Trie& tr, char* s) {
    int u = 0, n = strlen(s);
    for (int i = 0; i < n; i++) {
        int c = s[i] - 'a';
        u = tr.ch[u][c];
        if (tr.val[u]) {
            // 匹配到了模式串
        }
    }
}

int main() {
    Trie tr;
    char s[MAXN];
    int n, m;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> s;
        tr.insert(s, 1 << (i - 1));
    }
    build_ac(tr);
    cin >> m;
    for (int i = 1; i <= m; i++) {
        cin >> s;
        match(tr, s);
    }
    return 0;
}
用c++实现自动AC机

原文地址: https://www.cveoy.top/t/topic/b9bY 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录