您的位置:首页 > 理论基础 > 数据结构算法

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

2015-11-09 20:48 465 查看
最近两天都在做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 225
int num[1050];
int row
[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
[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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: