• 【模板】AC自动机


    (AC)自动机又称 (Trie) 图,是一个确定性有限状态自动机。具体来讲,通过在 (trie) 上定义一个 (fail) 转移函数,将 (trie) 的树形结构变成了一个图的结构。同时,根据 (DFA) 的性质,对于每个状态节点都要有关于字母表中所有字符的转移方式,在构建 (fail) 指针的同时,也完成了这个操作。
    (AC)自动机建立的时间复杂度为 (O(N)),匹配的时间复杂度为 (O(M)),其中 (N) 为所有模式串长度的总和,(M) 为匹配串长度的总和。

    代码如下

    #include <bits/stdc++.h>
    using namespace std;
    
    struct trie {
    	struct node {
    		int go[26], cnt;
    		node() : cnt(0) {
    			memset(go, -1, sizeof(go));
    		}
    	};
    	vector<node> t;
    	vector<int> fail;
    	int rt;
    	trie() : rt(0) {
    		t.emplace_back(node());
    	}
    	void insert(const string &s) {
    		int now = rt;
    		for (auto ch : s) {
    			if (t[now].go[ch - 'a'] == -1) {
    				t[now].go[ch - 'a'] = t.size();
    				t.emplace_back(node());
    			}
    			now = t[now].go[ch - 'a'];
    		}
    		t[now].cnt++;
    	}
    	void build_fail() {
    		fail.resize(t.size());
    		queue<int> q;
    		for (int i = 0; i < 26; i++) {
    			if (t[rt].go[i] == -1) {
    				t[rt].go[i] = rt;
    			} else {
    				q.push(t[rt].go[i]);
    			}
    		}
    		while (q.size()) {
    			int u = q.front();
    			q.pop();
    			for (int i = 0; i < 26; i++) {
    				if (t[u].go[i] != -1) {
    					fail[t[u].go[i]] = t[fail[u]].go[i];
    					q.push(t[u].go[i]);
    				} else {
    					t[u].go[i] = t[fail[u]].go[i];
    				}
    			}
    		}
    	}
    	int search(const string &s) {
    		int now = rt, ret = 0;
    		for (auto ch : s) {
    			now = t[now].go[ch - 'a'];
    			for (int i = now; i && t[i].cnt != -1; i = fail[i]) {
    				ret += t[i].cnt;
    				t[i].cnt = -1;
    			}
    		}
    		return ret;
    	}
    };
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(0), cout.tie(0);
    	int n;
    	cin >> n;
    	trie t;
    	for (int i = 0; i < n; i++) {
    		string s;
    		cin >> s;
    		t.insert(s);
    	}
    	t.build_fail();
    	string s;
    	cin >> s;
    	cout << t.search(s) << endl;
    	return 0;
    }
    
  • 相关阅读:
    第七章LED将为我闪烁:控制发光二极管
    第六章第一个Linux驱动程序:统计单词个数
    搭s3c6410开发板的测试环境读后感
    第四章源代码的下载和编译
    第三章Git使用入门(读后感)
    第二章:搭建Android开发环境(读后感)
    第一章:Android系统移植与驱动开发概述(读后感)
    函数和代码复用
    python的基本数据类型
    Python的语法元素
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10905526.html
Copyright © 2020-2023  润新知