单词统计 (AC自动机)

来源:互联网 发布:嵌入式linux裁剪 编辑:程序博客网 时间:2024/06/05 11:37
1118.单词统计Time Limit: 1000 MS    Memory Limit: 32768 KB
Total Submission(s): 12    Accepted Submission(s): 1
Description
给定一个字符串和若干个单词,统计这些单词在这个字符串中出现的次数。
Input
第一行为一个整数n(1 <= n <= 10000),表示单词的数量,之后n行每行一个单词,单词只由小写字母组成,最大长度为50。最后一行为一个字符串,也只由小写字母组成,最大长度1000000。
Output
一行n个用一个空格隔开的整数,表示每个单词出现的次数。
Sample Input
5aabbaabababaababa
Sample Output
4 2 2 2 1
#include<iostream>#include<stdio.h>#include<cstring>using namespace std;struct node{    node *fail;    node *next[26];    int count;    int count1;    node()    {        fail=NULL;        count=0;        count1=0;        memset(next,NULL,sizeof(next));    }}*q[500001];char keyword[51];char str[1000001];int head,tail;int num=0;int cnt[10001]={0};void insert(char *str,node *root){    node *p=root;    int i=0,index;    while(str[i])    {        index=str[i]-'a';        if(p->next[index]==NULL)            p->next[index]=new node();        p=p->next[index];        i++;    }    if(p->count==0)    {        p->count=1;        p->count1=++num;    }    else        cnt[++num]=-p->count1;}void build(node *root){    int i;    root->fail=NULL;    q[head++]=root;    while(head!=tail)    {        node *temp=q[tail++];        node *p=NULL;        for(i=0;i<26;i++)        {            if(temp->next[i]!=NULL)            {                if(temp==root)                    temp->next[i]->fail=root;                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=root;                }                q[head++]=temp->next[i];            }        }    }}           int query(node *root){    int i=0,index;    node *p=root;    while(str[i])    {        index=str[i]-'a';        while(p->next[index]==NULL&&p!=root)            p=p->fail;        p=p->next[index];        p=(p==NULL)?root:p;        node *temp=p;        while(temp!=root)        {            if(temp->count!=0)                cnt[temp->count1]+=temp->count;            temp=temp->fail;        }        i++;    }    return 0;}int main(){    int n;    head=tail=0;    node *root=new node;    scanf("%d",&n);    while(n--)    {        scanf("%s",keyword);        insert(keyword,root);    }    build(root);    scanf("%s",str);    query(root);    for(int i=1;i<=num;i++)        if(cnt[i]<0)            cnt[i]=cnt[-cnt[i]];    for(int i=1;i<num;i++)        printf("%d ",cnt[i]);    printf("%d",cnt[num]);    return 0;}

 
原创粉丝点击