hdu5880 Family View (AC自动机)

来源:互联网 发布:我知女人心迅雷下载 编辑:程序博客网 时间:2024/06/05 12:41

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5880

题意:

给你一些关键字,再给你一段文字,需要你将关键字屏蔽,换成‘*’;

解:

AC自动机解,记录下关键字的长度和出现的位置,再遍历输出一遍就好。

(但问题是我在pos数组记录长度输出一直WA,,费解呀)

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>using namespace std;const int maxn = 1e6+50;int pos[maxn];char s[maxn],str[maxn];struct Tries{    int nxt[maxn][27],fail[maxn],end[maxn],p[maxn];    int root,L;    int newnode(){        for(int i = 0; i < 26 ; i++ )            nxt[L][i]=-1;        p[L]=0;        end[L++]=0;    return L-1;    }    void init(){        L=0;        root = newnode();        //memset(p,0,sizeof(p));    }    void insert(char buf[]){        int len = strlen(buf);        int now = root;        for(int i = 0; i < len ; i++ )        {            if(nxt[now][buf[i]-'a'] == -1)                nxt[now][buf[i]-'a'] =newnode();            now = nxt[now][buf[i]-'a'];        }        end[now]=1 ;        p[now]=len;    }    void build(){        queue<int>Q;        fail[root] = root;        for(int i = 0; i < 26; i++ )            if(nxt[root][i]==-1)                nxt[root][i] = root;            else            {                fail[nxt[root][i]] = root;/* *** */                Q.push(nxt[root][i]);            }        while(!Q.empty())        {            int now = Q.front();            Q.pop();            for(int i = 0;i < 26; i++ )                if(nxt[now][i]==-1)//如果该节点的子节点都不存在,那么该子节点节点变为该节点的转移节点的子节点                    nxt[now][i] = nxt[fail[now]][i]; /* *** */                else//如果存在,那么该子节点的转移节点为该节点的转移节点的子节点,该子节点入队列                {                    fail[nxt[now][i]] = nxt[fail[now]][i];                    Q.push(nxt[now][i]);                }        }    }    void query(char buf[])    {        int len = strlen(buf);        int now = root;        memset(pos,0,sizeof(pos));        //int res = 0;        for(int i = 0;i < len ; i++ )//如果子节点存在,则顺着该链一直匹配下去;如果不存在就一直转移,直到存在或者转移到根节点(now会更新到根节点)        {            if(buf[i]>='a'&&buf[i]<='z')now=nxt[now][buf[i]-'a'];            else if(buf[i]>='A'&&buf[i]<='Z')now=nxt[now][buf[i]-'A'];            else {now=root;continue;}            int tmp = now;            while( tmp != root)            {                if(end[tmp]){                    pos[i+1] -= 1;                    pos[i - p[tmp]+1] += 1;                    break;                }                tmp = fail[tmp];            }        }        long long int sum=0;        for(int i=0;i<len;i++)        {            sum+=pos[i];            if(sum>0)printf("*");            else printf("%c",buf[i]);        }        printf("\n");;    }};Tries AC;int main(){    int t;    scanf("%d",&t);    while(t--)    {        int n;        scanf("%d",&n);        AC.init();        while(n--)        {            scanf("%s",s);            AC.insert(s);        }        AC.build();        getchar();        gets(str);        AC.query(str);    }    return 0;}


原创粉丝点击