您的位置:首页 > 其它

uva 1449 AC自动机

2015-10-08 19:31 302 查看
题意:

求在匹配串中出现次数最多的模式串。


思路:

AC自动机裸题。 稍微改一下。。


code:

#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <map>
using namespace std;
int hs[1600];
int n;
int Next[50010][26],fail[50010],End[50010];
char a[151][160];
map<string, int> m;
map<int, string> m2;
int cnt;
struct Trie
{
int root,L;
int newnode()
{
for(int i = 0;i < 26;i++)
Next[L][i] = -1;
End[L++] = 0;
return L-1;
}
void init()
{
L = 0;
root = newnode();
}
void insert(const char buf[], int id)
{
int len = strlen(buf);
int now = root;
for(int i = 0;i < len;i++)
{
if(Next[now][buf[i]-'a'] == -1)
Next[now][buf[i]-'a'] = newnode();
now = Next[now][buf[i]-'a'];
}
End[now] = id;
}
void build()
{
queue<int>Q;
fail[root] = root;
for(int i = 0;i < 26;i++)
if(Next[root][i] == -1)
Next[root][i] = root;
else
{
fail[Next[root][i]] = root;
Q.push(Next[root][i]);
}
while( !Q.empty() )
{
int now = Q.front();
Q.pop();
for(int i = 0;i < 26;i++)
if(Next[now][i] == -1)
Next[now][i] = Next[fail[now]][i];
else
{
fail[Next[now][i]]=Next[fail[now]][i];
Q.push(Next[now][i]);
}
}
}
void query(char buf[])
{
memset(hs, 0, sizeof(hs));
int len = strlen(buf);
int now = root;
for(int i = 0;i < len;i++)
{
now = Next[now][buf[i]-'a'];
int temp = now;
while( temp != root )
{
if(End[temp])
hs[End[temp]]++;
temp = fail[temp];
}
}
int res1 = *max_element(hs+1, hs+cnt+1);
printf("%d\n", res1);
for(int i=1; i<=cnt; i++){
if(hs[i] == res1){
printf("%s\n", m2[i].c_str());
}
}
}
};
char str[1001000];
string tmp;
int main(){
Trie t;
while(cin>>n&&n){
m.clear(); m2.clear();
t.init();
cnt = 0;
for(int i=1; i<=n; i++){
cin>>tmp;
if(m[tmp]) continue;
m[tmp] = ++cnt;
m2[cnt] = tmp;
t.insert(tmp.c_str(), cnt);
}
t.build();
scanf("%s", str);
t.query(str);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uva AC自动机