zoukankan      html  css  js  c++  java
  • 【模板】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;
    }
    
  • 相关阅读:
    用Python发生RestFul API POST和GET请求
    C# 8.0中的新功能
    A股数据分析之收集数据:股票列表和股价
    A股数据分析之收集数据:公司详细信息
    VS 2019中修改C#语言版本
    Weak Event Manager
    在WPF中使用MVVM的方式关闭窗口
    C# GDI绘制仪表盘(纯代码实现)
    C#中实现文件拖放打开的方法
    C#设置自定义文件图标实现双击启动
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10905526.html
Copyright © 2011-2022 走看看