zoukankan      html  css  js  c++  java
  • 【模板】AC自动机

    模板1

    #include <queue>
    #include <cstdio>
    #include <cstring>
    #define N 1000001
    
    int n, cnt, ans;
    int next[N][26], val[N], fail[N];
    char s[N];
    std::queue <int> q;
    
    inline void insert()
    {
    	int i, x, now = 0, m = strlen(s + 1);
    	for(i = 1; i <= m; i++)
    	{
    		x = s[i] - 'a';
    		if(!next[now][x])
    			next[now][x] = ++cnt;
    		now = next[now][x];
    	}
    	val[now]++;
    }
    
    inline void make_fail()
    {
    	int i, now;
    	for(i = 0; i < 26; i++)
    		if(next[0][i])
    			q.push(next[0][i]);
    	while(!q.empty())
    	{
    		now = q.front();
    		q.pop();
    		for(i = 0; i < 26; i++)
    		{
    			if(!next[now][i])
    			{
    				next[now][i] = next[fail[now]][i];
    				continue;
    			}
    			fail[next[now][i]] = next[fail[now]][i];
    			q.push(next[now][i]);
    		}
    	}
    }
    
    inline void ac()
    {
    	int i, j, now = 0, m = strlen(s + 1);
    	for(i = 1; i <= m; i++)
    	{
    		now = next[now][s[i] - 'a'];
    		for(j = now; j && ~val[j]; j = fail[j])
    		{
    			ans += val[j];
    			val[j] = -1;
    		}
    	}
    }
    
    int main()
    {
    	int i;
    	scanf("%d", &n);
    	for(i = 1; i <= n; i++)
    	{
    		scanf("%s", s + 1);
    		insert();
    	}
    	make_fail();
    	scanf("%s", s + 1);
    	ac();
    	printf("%d
    ", ans);
    	return 0;
    }
    

      

    模板2

    #include <queue>
    #include <cstdio>
    #include <cstring>
    #define N 1000001
    #define max(x, y) ((x) > (y) ? (x) : (y))
    
    int n, cnt;
    int val[N], next[N][26], ans[N], fail[N];
    char s1[151][71], s2[N];
    std::queue <int> q;
    
    inline void insert(int k, char *s)
    {
    	int i, x, now = 0, m = strlen(s + 1);
    	for(i = 1; i <= m; i++)
    	{
    		x = s[i] - 'a';
    		if(!next[now][x])
    			next[now][x] = ++cnt;
    		now = next[now][x];
    	}
    	val[now] = k;
    }
    
    inline void make_fail()
    {
    	int i, now;
    	for(i = 0; i < 26; i++)
    		if(next[0][i])
    			q.push(next[0][i]);
    	while(!q.empty())
    	{
    		now = q.front();
    		q.pop();
    		for(i = 0; i < 26; i++)
    		{
    			if(!next[now][i])
    			{
    				next[now][i] = next[fail[now]][i];
    				continue;
    			}
    			fail[next[now][i]] = next[fail[now]][i];
    			q.push(next[now][i]);
    		}
    	}
    }
    
    inline void ac(char *s)
    {
    	int i, j, now = 0, m = strlen(s + 1);
    	for(i = 1; i <= m; i++)
    	{
    		now = next[now][s[i] - 'a'];
    		for(j = now; j; j = fail[j])
    			if(val[j])
    				ans[val[j]]++;
    	}
    	for(i = 1; i <= n; i++)
    		ans[0] = max(ans[0], ans[i]);
    	printf("%d
    ", ans[0]);
    	for(i = 1; i <= n; i++)
    		if(ans[i] == ans[0])
    			printf("%s
    ", s1[i] + 1);
    }
    
    int main()
    {
    	int i;
    	while(scanf("%d", &n) && n)
    	{
    		cnt = 0;
    		memset(val, 0, sizeof(val));
    		memset(ans, 0, sizeof(ans));
    		memset(next, 0, sizeof(next));
    		memset(fail, 0, sizeof(fail));
    		for(i = 1; i <= n; i++)
    		{
    			scanf("%s", s1[i] + 1);
    			insert(i, s1[i]);
    		}
    		make_fail();
    		scanf("%s", s2 + 1);
    		ac(s2);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    KSTORE日常工作遇到问题总结
    调用bat文件执行java文件
    腾讯课堂十大Excel函数
    《将博客搬至CSDN》
    oracle 累加功能,累加百分比
    验证身份证是否合法
    远程登录修改密码
    二叉树的遍历
    nginx启动、重启、关闭
    状态模式-State-订单状态
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/7520418.html
Copyright © 2011-2022 走看看