因为做题的需要,花了点时间学了字典树。原来字典树是那么的简单,我还以为很难呢。
在我看来,字典树就是为了方便查找。
从下面篇博客就能知道为什么在我看来字典树就是为了查找。
http://blog.youkuaiyun.com/u012501262/article/details/21695033
下面先看字典树的节点的构造:
const int MAX = 26;
//为什么是26,因为是26个字母,如果分大小写那么就是52,如果再加入数字,那就是62
struct node
{
int k;//该变量的类型根据需求变化
node *next[MAX];//
node()
{
count = 0;
flag = 0;
for(int i=0;i!=MAX;++i)
{
next[i] = NULL;
}
}
};
给定一个单词,把单词的每个字符作为一个节点,前一个字母是后一个字符的双亲节点。
例如给定一个单词ab
那么就要创建一个一个节点,让root->next[0] = new node;
再 root->next[0]->next[1] = new node;
字典树是根据next的指向是否为空来判断该字母是否存在.
下面是建树:
class trie//字典树类
{
public:
trie(){root = new node;}
void creat_trie(string str);
int search(string str);
void print_all();
private:
node *root;
};
void trie ::creat_trie(string str)//字典树的创建
{
node *current = root;
node *fresh;
int index;
for(int i=0;i<str.size();++i)
{
index = str[i] - 'a';
if(current->next[index] == NULL)//如果next的指向为空,该字典树不存在该前缀,要创建
{
fresh = new node;
current->next[index] = fresh;
current = current->next[index];
current->k = 1;//该前缀的数量
}
else
{//如果不为空,则增加该前缀的数量
current = current->next[index];
current->k++;
}
}
}
懂得建树,就明白如何查找了
下面是查找:
int trie:: search(string str)
{
node *current;
current = root;
int index;
for(int i=0;i!=str.size();++i)
{
index = str[i] - 'a';
current = current->next[index];
if(current == NULL)//如果指向为空,则字典树中不存在以str为前缀的单词
return 0;
}
if(current != NULL)//存在
return current->k;//返回以str为前缀的单词的数量
}
完整的程序:
#include<iostream>
using namespace std;
const int MAX = 26;
struct node
{
int k;//根据需求改变
node *next[MAX];
node()
{
k = 0;
for(int i=0;i!=MAX;++i)
{
next[i] = NULL;
}
}
};
class trie//字典树类
{
public:
trie(){root = new node;}
void creat_trie(string str);
int search(string str);
void print_all();
private:
node *root;
};
void trie ::creat_trie(string str)//字典树的创建
{
node *current = root;
node *fresh;
int index;
for(int i=0;i<str.size();++i)
{
index = str[i] - 'a';
if(current->next[index] == NULL)
{
fresh = new node;
current->next[index] = fresh;
current = current->next[index];
current->k = 1;
}
else
{
current = current->next[index];
current->k++;
}
}
}
int trie:: search(string str)
{
node *current;
current = root;
int index;
for(int i=0;i!=str.size();++i)
{
index = str[i] - 'a';
current = current->next[index];
if(current == NULL)
return 0;
}
if(current != NULL)
return current->k;
}
int main()
{
trie t;
string str;
getline(cin,str);
while(str != "")
{
t.creat_trie(str);
getline(cin,str);
}
while(getline(cin,str))
{
cout<<t.search(str)<<endl;
}
}