HDU ACM 2222->AC自动机模版题(入门题)

题意:预先给你一些单词,然后给你一个字符串,在判断有多少个单词出现在这个字符串中。

分析:使用AC自动机解决。下面是自己写的类模版。可以直接使用。最后记得释放内存。

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

#define LETTER_COUNT 26
class AC_Automation
{
private:
	struct Node
	{
		Node* fail;                  //失败指针
		Node* next[LETTER_COUNT];  //Tire树节点的子节点
		int count;                    //是否为该单词的最后一个节点
		Node()
		{
			fail=NULL;
			count=0;
			memset(next,NULL,sizeof(next));
		}
	};
	Node* m_sroot;

	void Delete(Node* p);
public:
	AC_Automation(){ m_sroot=(Node*)new Node();}
	~AC_Automation(){ Delete(m_sroot);}

	void AddWord(char* str);      //添加一个单词
	void Build_AC_Automation();
	int GetMatchingCount(char* str);
};

int AC_Automation::GetMatchingCount(char* str)
{
	int cnt=0,index;
	Node* p,*temp;

	p=m_sroot;
	while(*str)
	{
		index=*str-'a';
		while(p->next[index]==NULL && p!=m_sroot) p=p->fail;
		p=p->next[index];
		p=(p==NULL)?m_sroot:p;

		temp=p;
		while(temp!=m_sroot && temp->count!=-1)    //确保当前字符前面包含的所有单词都被匹配
		{
			cnt+=temp->count;
			temp->count=-1;
			temp=temp->fail;
		}
		str++;
	}
	return cnt;
}

void AC_Automation::Delete(Node* p)
{
	for(int i=0;i<LETTER_COUNT;i++)
		if(p->next[i]!=NULL)
			Delete(p->next[i]);
	delete p;
}

void AC_Automation::Build_AC_Automation()
{
	int i;
	Node *temp,*p;
	queue<Node*> q; //队列,用于BFS,建立失败指针

	m_sroot->fail=NULL;
	q.push(m_sroot);
	while(!q.empty())
	{
		temp=q.front();
		q.pop();
		p=NULL;
		for(i=0;i<LETTER_COUNT;i++)
		{
			if(temp->next[i]!=NULL)
			{
				if(temp==m_sroot) temp->next[i]->fail=m_sroot;
				else
				{
					p=temp->fail;
					while(p!=NULL)
					{
						if(p->next[i]!=NULL)
						{
							temp->next[i]->fail=p->next[i];
							break;
						}
						p=p->fail;
					}
					if(p==NULL) temp->next[i]->fail=m_sroot;
				}
				q.push(temp->next[i]);        //子节点如队列
			}
		}
	}
}

void AC_Automation::AddWord(char* str)
{
	Node* p=m_sroot;
	int i=0;
	int index;

	while(*str)
	{
		index=*str-'a';
		if(p->next[index]==NULL) p->next[index]=(Node*)new Node();
		p=p->next[index];
		str++;
	}
	p->count++;             //单词的最后一个节点加1,单表新加入一个单词
}

int main()
{
	int T,N,i;
	char a[51];
	char b[1000001];

	cin>>T;
	while(T--)
	{
		AC_Automation ac_auto;
		cin>>N;
		for(i=0;i<N;i++)
		{
			cin>>a;
			ac_auto.AddWord(a);
		}
		ac_auto.Build_AC_Automation();
		cin>>b;
		cout<<ac_auto.GetMatchingCount(b)<<endl;
	}
	return 0;
}
时间: 2024-11-10 17:10:04

HDU ACM 2222->AC自动机模版题(入门题)的相关文章

HDU 2222 AC自动机(模版题)

Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 70290    Accepted Submission(s): 23917 Problem Description In the modern time, Search engine came into the life of everybody lik

HDU 2222 AC自动机模板题

题目: http://acm.hdu.edu.cn/showproblem.php?pid=2222 AC自动机模板题 1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 using namespace std; 5 char key[55]; 6 char des[1111111]; 7 struct node{ 8 node *fail; 9 node *next[26]; 10 int cnt;

HDU 5384 AC自动机模版

点击打开链接 题意:n个A,m个B,对于每个A,输出所有B在A中出现的次数 思路:和AC自动机模版题2222相同,唯一的区别就是n个A不能开二维,自己处理一下就OK了 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> using namespace std; typedef long long ll

HDU 2896 病毒侵袭(AC自动机模版题)

AC自动模版题,中文题目就不叙述题意了啊. AC自动主要是构造出字典树之后找到fail指针的跳转,类似于KMP里面的next数组的跳转啊,注意这里是多模式跳转.意思就是这个串跳到下一个串的什么位置啊. 先帖一下,做多了再一起总结吧. 病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11347    Accepted Submi

hdu 2222 AC自动机(模板题)

<题目链接> 题目大意: 给你一些单词,和一个字符串,问你这个字符串中含有多少个上面的单词. 解题分析: 这是多模匹配问题,如果用KMP的话,对每一个单词,都跑一遍KMP,那么当单词数量非常多的时候,耗时会非常多,所以这里用到了AC自动机,这是一种类似于Trie树的数据结构,但是同时,它也用到了KMP算法中 next数组的思想. 下面是AC自动机指针形式的题解: #include <stdio.h> #include <stdlib.h> #include <st

HDU 2222 ----AC自动机

Problem Description In the modern time, Search engine came into the life of everybody like Google, Baidu, etc.Wiskey also wants to bring this feature to his image retrieval system.Every image have a long description, when users type some keywords to

hdoj 2222 Keywords Search 【AC自己主动机 入门题】 【求目标串中出现了几个模式串】

Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 44687    Accepted Submission(s): 14103 Problem Description In the modern time, Search engine came into the life of everybody li

hdu 2222 AC自动机(可做模板)

Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 50101    Accepted Submission(s): 16083 Problem Description In the modern time, Search engine came into the life of everybody li

HDU 1233 还是畅通工程【最小生成树入门题,Kruskal算法+Prim算法】

还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 39929    Accepted Submission(s): 18144 Problem Description 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路

2017多校第6场 HDU 6096 String AC自动机

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6096 题意:给了一些模式串,然后再给出一些文本串的不想交的前后缀,问文本串在模式串的出现次数. 解法: 因为要求前缀后缀都包含的个数,所以可以把字符串a转换成a#a这样一个字符串,比如abca就转换成abca#abca 然后对于一组前缀a后缀b转换成b{a,比如ab ca,就是ca{ab, 然后对前缀后缀的串建立AC自动机,让主串去匹配,如上述例子,ca{ab满足为abca{abca的一个子串,也就