/* Trie树,又叫做字典树,是一种用来求字符串前缀出现次数的数据结构。Trie树很像有限状态机,每个节点虽然不存储具体的键,但是都对应一个字符串*/
#include <iostream>
using namespace std;
#define MAX 26
/*定义节点结构*/
typedef struct TrieNode
{
int nCount;
TrieNode* next[MAX];
}TrieNode;
/*初始化Trie树*/
void InitTrie(TrieNode * &root)
{
root = NULL;
}
/*创建一个新的Trie节点*/
TrieNode* CreateTrieNode()
{
TrieNode *p = new TrieNode;
p->nCount = 1;
for (int i = 0;i < MAX;i++)
{
p->next[i] = NULL;
}
return p;
}
/*根据一个字符串插入一个节点*/
void InsertTrieNode(TrieNode* &root,char* s)
{
TrieNode* p;
int i = 0;
if (!root)
{
root = CreateTrieNode();
}
p = root;
while(s[i])
{
int k = s[i] - 'a';//求字符偏移,确定在next[MAX]中的位置
if (!p->next[k])
{
p->next[k] = CreateTrieNode();
p = p->next[k];
}
else
{
p->next[k]->nCount++;
p = p->next[k];
}
i++;
}
}
/*根据一个字串查找以该字串为前缀的字符串的个数*/
int SearchTrie(TrieNode* &root,char* s)
{
TrieNode* p = root;
int i = 0;
if (!p)
{
return 0;
}
while(s[i])
{
int k = s[i] - 'a';
if (!p->next[k])
{
return 0;
}
else
{
p = p->next[k];
}
i++;
}
return p->nCount;
}
int main(int argc,char** argv)
{
char s[15] = {0};
TrieNode *Root = NULL;
InitTrie(Root);
while(gets(s) && s[0])
{
InsertTrieNode(Root,s);
memset(s,0,15);
}
cout<<"输入要查询的字符串:\n"<<endl;
while(gets(s))
{
cout<<SearchTrie(Root,s)<<endl;
memset(s,0,15);
}
return 0;
}