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;
    }
    
  • 相关阅读:
    数据绑定表达式语法(Eval,Bind区别)
    使用博客园的第一件事 自定义主题
    sql2000 跨服务器复制表数据
    使用UpdatePanel 局部刷新出现中文乱码的解决方法!!
    MMC不能打开文件MSC文件
    sql 日期 、时间相关
    loaded AS2 swf call function in AS3 holder
    Rewrite the master page form action attribute in asp.net 2.0
    100万个不重复的8位的随机数
    flash 中实现斜切变型
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10905526.html
Copyright © 2011-2022 走看看