OJ-Problems-Source/HDOJ/5880_wangdongkai.cpp

136 lines
3.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* HDU 5880 Family View
* 把文本串中所有的模式串换为等长度的'*'
*
* AC自动机
* 将模式串建立AC自动机然后进行文本串匹配求出文本串的每个前缀
* 所包含的最长后缀并且是模式串用pos数组记录位置然后扫描一遍输出即可。
*/
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int MAXN = 1000000+100;
char str[MAXN];
int pos[MAXN];
struct Aho_Corasick
{
const static int maxnode = 1000000+100;
const static int type = 26;
int next[maxnode][type],fail[maxnode],end[maxnode],l[maxnode];
int root,L;
int newnode()
{
for(int i = 0;i<type;i++)
next[L][i] = -1;
l[L]=0;
end[L++] = -1;
return L-1;
}
void init()
{
L = 0;
root = newnode();
}
void insert(char* str)
{
int len = strlen(str);
int now = root;
for(int i = 0;i < len;i++)
{
int id=str[i]-'a';
if(next[now][id] == -1)
next[now][id] = newnode();
now=next[now][id];
}
end[now]=1;
l[now]=len;
}
void build()
{
queue<int>Q;
fail[root] = root;
for(int i = 0;i < type;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 < type;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 work(char* str)
{
int id;
int len = strlen(str);
int now = root;
memset(pos,0,sizeof(pos));
for(int i = 0;i < len;i++)
{
if(str[i]>='A'&&str[i]<='Z') id=str[i]-'A';
else if(str[i]>='a'&&str[i]<='z') id=str[i]-'a';
else continue;
now = next[now][id];
int temp=now;
while(temp != root)
{
if(end[temp] != -1)
{
pos[i+1]-=1;
pos[i-l[temp]+1]+=1;
break;
}
temp = fail[temp];
}
}
long long cnt=0;
for(int i=0;i<len;i++)
{
cnt+=pos[i];
if(cnt<=0) printf("%c",str[i]);
else printf("*");
}
printf("\n");
}
}AC;
int main()
{
int T;
int n;
scanf("%d",&T);
while(T--)
{
AC.init();
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",str);
AC.insert(str);
}
AC.build();
getchar();
gets(str);
AC.work(str);
}
return 0;
}