ac自动机匹配new与malloc分配结点空间问题
程序代码:#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <malloc.h>
const int kind = 26;//表示26个字母的编号
struct Mynode
{
struct Mynode *next[kind];//表示每个节点都可以有26个字母作为其孩子
struct Mynode *fail;
int flag;//标志以该节点回溯的单词可以匹配
Mynode()
{
fail = NULL;
flag = 0;
memset(next, NULL, sizeof(next));//所有的孩子都初始化为NULL
}
};//
Mynode *lpMyseque[500001];//指针队列用来构造失败指针的
char szMsg[256];//单词
char str[100000];//文本
int start = -1;//队列的头指针
int last = -1;//队列的末尾指针
void CreateTree(Mynode* root);//创建字典树
void InsertWord(char* keyword, Mynode* root);//插入单词
void CreateAc(Mynode* root);//创建自动机
int FindMacthWord(Mynode* root);//返回匹配的单词数目
void CreateTree(Mynode* root)
{
int n;
scanf("%d", &n);//输入单词数
getchar();
while(n)
{
gets(szMsg);
InsertWord(szMsg, root);
n--;
}
return;
}
void InsertWord(char* keyword, Mynode* root)
{
Mynode* p = root;
int i = 0;
int index;
while(keyword[i])
{
index = keyword[i] - 'a';//转化为0到25数字
if (p->next[index] == NULL)
{
p->next[index] = new Mynode();//为单词中的每一个字符分配空间
//p->next[index] = (Mynode*)malloc(sizeof(Mynode));
}
p = p->next[index];//p指向该新建立的节点
i++;
}
p->flag++;//该单词的标志
return;
}
//构造失败指针
void CreateAc(Mynode* root)
{
int i;
root->fail = NULL;//根节点的失败指针指向空
lpMyseque[++start] = root;//进队列
while(start != last)
{
Mynode* temp = lpMyseque[++last];//出队列
Mynode* p = NULL;
for (i=0; i<26; i++)
{
if (temp->next[i] != NULL)
{
if (temp == root)
{
temp->next[i]->fail = root;//root后的第一个节点失败指针指向root
}
//不是第一个节点的
else
{
p = temp->fail;
while(p != NULL)
{
if (p->next[i] != NULL)
{
temp->next[i]->fail = p->next[i];
break;
}
//如果在p->next中没有找到与temp->next相同的字符
p = p->fail;//就把p指向失败节点
}
//如果p中指向的所有的失败节点都没有与之相同的孩子
if (NULL == p)
{
temp->next[i]->fail = root;//temp孩子的失败指针就指向root
}
}
lpMyseque[++start] = temp->next[i];//进入队列
}
}
}
return;
}
//寻找匹配的单词的个数
int FindMacthWord(Mynode* root)
{
int i = 0;
int count = 0;//计算匹配的单词的个数
int index;//字符的标号
int len = strlen(str);//文本的长度
Mynode* 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;
Mynode* temp = p;
while(temp != root && temp->flag != -1)
{
count += temp->flag;//如果是单词的末尾字符flag为1否则就是0
temp->flag = -1;
temp = temp->fail;
}
i++;
}
return count;
}
int main()
{
//Mynode* root = (Mynode*)malloc(sizeof(Mynode));;
Mynode* root = new Mynode();
CreateTree(root);
gets(str);
CreateAc(root);
printf("%d\n",FindMacthWord(root));
return 0;
}我用了两种方法来开辟结点的空间。第一种方法为new
Mynode* root = new Mynode();
第二种为malloc
Mynode* root = (Mynode*)malloc(sizeof(Mynode));
new方法运行没有错,malloc运行方法程序崩溃。出错在InsertWord函数中
if (p->next[index] == NULL)
或者
p->flag++;
这两个地方。
有兴趣的帮忙看看!!谢谢
[ 本帖最后由 ycc892009 于 2010-11-18 23:24 编辑 ]


