问题:在百度或大型网站,你输入“中国”出现“中国制造”,“中国创造”,好多以”中国“为前缀的字符串
这个问题在搜索引擎中常用到,用到Trie树
本文参考了http://www.cnblogs.com/dolphin0520/archive/2011/10/11/2207886.html,深受启发
一.Trie树的原理
利用串构建一个字典树,这个字典树保存了公共前缀信息
下面以英文单词构建的字典树为例,这颗Trie树种每个节点包括26个孩子节点,因为英文中有26个字母
节点的结构体
#define MAX 26
typedef struct TrieNode
{
bool isStr;
struct TrieNode *next[MAX];
}Trie;
查找的时候,假设字符串长度为len,用BST代价为len*log2(n),用Trie树时间复杂度为len
typedef struct TrieNode
{
bool isStr;
struct TrieNode *next[MAX];
}Trie;
//在以root的Trie树中插入字符串 s
void insert(Trie *root,const char *s)
{
if(root==NULL||*s=='\0')
return ;
int i;
Trie *p=root;
while(*s!='\0')
{
if(p->next[*s-'a']==NULL)
{
Trie *temp=new Trie;
for(i=0;i<MAX;i++)
temp->next[i]=NULL;
temp->isStr=false;
p->next[*s-'a']=temp;
p=p->next[*s-'a'];
}else
{
p=p->next[*s-'a'];
}
s++;
}
p->isStr=true;
}
//查找每个单词存在否
int search(Trie *root,const char *s)
{
Trie *p=root;
while(p!=NULL&&*s!='\0')
{
p=p->next[*s-'a'];
s++;
}
return (p&&p->isStr==true);
}
//visit p代表找到的前缀的最后单词,str为从root->next---->p的字符串 用递归的方法
void vist(Trie *p,string str)
{
if(!p||p->next==NULL)
return;
if(p->isStr)
{
cout<<str<<endl;
}
for(int i=0;i<MAX;i++)
{
char ch='a'+i;
vist(p->next[i],str+ch);
}
}
int search_2(Trie *root,const char *s)//找出含有 *s前缀的所有单词
{
Trie *p=root;
string str(s);
while(p!=NULL&&*s!='\0')
{
p=p->next[*s-'a'];
s++;
}
if(p==NULL)
{
return 0;
}
int ret=(p&&p->isStr==true);
vist(p,str);
cout<<endl<<endl;
return ret;
}
//删除root的内存
void del(Trie *root)
{
int i;
for(i=0;i<MAX;i++)
{
if(root->next[i]!=NULL)
{
del(root->next[i]);
}
}
delete root;
}
int _tmain(int argc, _TCHAR* argv[])
{
int i;
int n,m;
char s[100]={'\0'};
Trie *root=new Trie;
for(i=0;i<MAX;i++)
{
root->next[i]=NULL;
}
root->isStr=false;
int cycle=1;
cout<<"exit please input 'end' "<<endl;
while(cycle)
{
cin>>s;
if(!strcmp(s,"end"))
{
cycle=0;
}else
{
insert(root,s);
}
}
cycle=1;
cout<<"exit search please input 'end' "<<endl;
while(cycle)
{
cin>>s;
if(!strcmp(s,"end"))
{
cycle=0;
}else{
if(search_2(root,s)==1)
cout<<s<<" found "<<endl;
else
cout<<s<<" not found "<<endl;
}
}
del(root);
return 0;
}