数据结构 文学研究助手(AC自动机)

来源:互联网 发布:单片机汇编语言基础 编辑:程序博客网 时间:2024/05/14 21:03

最近两天都在做AC自动机,刚好数据结构实验可以用,比KMP算法好的地方是文章只要扫描一遍,大大节省了时间,但同时占的内存变大了,简单地说就是,空间换时间。

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <algorithm>#include <malloc.h>#include <queue>using namespace std;#define M 25#define N 10#define maxn 225int num[1050];int row[N][1000];  //存储行号struct Trie{    Trie *fail,*next[130];    int last;    Trie()    {        for(int i=0;i<130;i++)            next[i]=NULL;        fail=NULL;        last=-1;    }}*root;void inserttrie(char *str,int k){    int len=strlen(str);    Trie *p=root;    for(int i=0;i<len;i++)    {        int id=str[i]-' ';        if(p->next[id]==NULL)        {            p->next[id]=new Trie;        }        p=p->next[id];    }    p->last=k;}void buildfail(){    Trie *son,*temp,*p=root;    queue<struct Trie*>que;    que.push(p);    while(!que.empty())    {        temp=que.front();        que.pop();        for(int i=0;i<130;i++)        {            son=temp->next[i];            if(son!=NULL)            {                if(temp==root)son->fail=root;                else                {                    p=temp->fail;                    while(p)                    {                        if(p->next[i])                        {                            son->fail=p->next[i];                            break;                        }                        p=p->fail;                    }                    if(!p)son->fail=root;                }                que.push(son);            }        }    }}void querry(char *str,int m){    int len=strlen(str);    Trie *p=root;    Trie *temp;    for(int i=0;i<len;i++)    {        if(str[i]==' ')        {            p=root;            continue;        }        else        {            int id=str[i]-' ';            while(p!=root&&p->next[id]==NULL)p=p->fail;            p=p->next[id];            if(!p)p=root;            temp=p;            while(temp!=root)            {                if(temp->last>=0)                {                    num[temp->last]++;                    row[temp->last][m]=1;                }                temp=temp->fail;            }        }    }}int main(){    int n;    char str[N][M];     //查询词    char text[maxn];   //每一行字符串    char name[50];     //小说路径    FILE *fp;    printf("输入查询单词个数:");    scanf("%d",&n);    memset(num,0,sizeof(num));    memset(row,0,sizeof(row));    root=new Trie;    for(int i=1;i<=n;i++)    {        printf("输入第%d个查询词:",i);        scanf("%s",str[i]);        inserttrie(str[i],i);    }    buildfail();    printf("输入文件路径:");    scanf("%s",name);    if (!(fp=(fopen(name,"r"))))   //打开小说文件    {        printf("Open file error!\n");        exit(0);    }    int k=1; //行号    while (!feof(fp))    {        fgets(text,maxn,fp);     //从小说文件中读取一行字符串,存入text串中        querry(text,k);        k++;                      //行号加1,在下一行中寻找    }    for(int i=1;i<=n;i++)    {        int flag=0;        printf("%s :",str[i]);        for(int j=0;j<1000;j++)        {            if(row[i][j])            {                flag=1;                printf("第%d行 ",j);            }        }        if(!flag)            printf("没有此词");        printf("\n");    }    return 0;}
0 0
原创粉丝点击