您的位置:首页 > 其它

hiho刷题日记——第四天Trie图

2015-11-05 16:10 260 查看
用和kmp相似的思路,将trie树变为trie图。以用于在长篇文章中查找是否存在字典中的单词。

在此强调本文中的‘根’和一般的树中的‘根’不一样!

1.建立trie树

①建立一个结点结构体和初始化函数

typedef struct node{

bool isEnd;//结点是否为单词的结尾

struct node* trie;//结点的根(这里的根和一般的树的根不一样,但是怎么解释呢。不知道啊。)

struct node* next[26];

}TrieNode;

void initNode(TrieNode *p)

{

p->isEnd = 0;

for(int i=0;i<26;i++)

p->next[i]=NULL;

}

②建立一个head结点并初始化。

③建立一个headTrie结点作为head的根,并将其所有的next指向head。

④对于输入单词的处理:

输入一个字符串并扫描,只要还没结束:
并判断是否存在对应字符的子结点。
若存在,转到子结点;否者建一个子结点并转到该结点。
当单词扫描结束时,将最后一个结点的isEnd属性标为true。
void makeTrie(char *w)

{

int i=0;

TrieNode* p=&head;

while(w[i])

{

if(p->next[w[i]-97])

{

p=p->next[w[i]-97];

}

else

{

TrieNode *q=(TrieNode *)malloc(sizeof(TrieNode));

initNode(q);

p->next[w[i]-97]=q;

p=q;

}

i++;

}

p->isEnd=1;

}

2.建立trie图

用广度遍历。将&head加入遍历队列,并将head.trie赋值为&headTrie作为head的根。

只要遍历队列里还有元素,则做一下操作:

①先取出元素。

②判断是否存在对应字符的子结点。

若有,则将其子结点加入遍历队列,并将其子结点的根结点设为其根结点的对应字符的子结点。。。。。文字好绕,上代码p->next[i]->trie=p->trie->next[i];

若无,则将其对应的子结点设为其根结点的对应字符的子结点。p->next[i]=p->trie->next[i];

这里就是用的kmp的思想。

void makeTrieMap()

{

int front=0,rear=0;

queue[rear++]=&head;

head.trie=&headTrie;

while(front<rear)

{

TrieNode* p=queue[front++];

for(int i=0;i<26;i++)

{

if(p->next[i]!=NULL)

{

queue[rear++]=p->next[i];

p->next[i]->trie=p->trie->next[i];

}

else

{

p->next[i]=p->trie->next[i];

}

}

}

}

3.使用trie图

扫描文章。

从head开始对比,一直照着next来跳转。直达有一个结点的isEnd为true。说明找到字典中的某个单词了。返回true;

否则直到扫描结束都没找到单词,返回false。

bool find(char *s)

{

int i=0;

TrieNode* p=&head;

while(s[i])

{

p=p->next[s[i]-97];

if(p->isEnd) return true;

i++;

}

return false;

}

题目全代码:

#include<cstdio>

#include<cstdlib>

using namespace std;

typedef struct node{

bool isEnd;

struct node* trie;

struct node* next[26];

}TrieNode;

TrieNode head;

TrieNode headTrie;

TrieNode* queue[1000000+1];

void initNode(TrieNode *p)

{

p->isEnd = 0;

for(int i=0;i<26;i++)

p->next[i]=NULL;

}

void makeTrie(char *w)

{

int i=0;

TrieNode* p=&head;

while(w[i])

{

if(p->next[w[i]-97])

{

p=p->next[w[i]-97];

}

else

{

TrieNode *q=(TrieNode *)malloc(sizeof(TrieNode));

initNode(q);

p->next[w[i]-97]=q;

p=q;

}

i++;

}

p->isEnd=1;

}

void makeTrieMap()

{

int front=0,rear=0;

queue[rear++]=&head;

head.trie=&headTrie;

while(front<rear)

{

TrieNode* p=queue[front++];

for(int i=0;i<26;i++)

{

if(p->next[i]!=NULL)

{

queue[rear++]=p->next[i];

p->next[i]->trie=p->trie->next[i];

}

else

{

p->next[i]=p->trie->next[i];

}

}

}

}

bool find(char *s)

{

int i=0;

TrieNode* p=&head;

while(s[i])

{

p=p->next[s[i]-97];

if(p->isEnd) return true;

i++;

}

return false;

}

int main()

{

int N;

char word[1000000+1];

char str[1000000+1];

initNode(&head);

for(int i=0;i<26;i++)

headTrie.next[i]=&head;

scanf("%d",&N);

while(N--)

{

scanf("%s",word);

makeTrie(word);

}

makeTrieMap();

scanf("%s",str);

if(find(str)) printf("YES");

else printf("NO");

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: