1、定义:
又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
2、性质:
根节点不包含字符,除根节点外每一个节点都只包含一个字符;
从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串;
每个节点的所有子节点包含的字符都不相同。
3、操作实现(查询,插入时,一个字符串s,指针p指向根节点)
(1)初始化
Tire树仅包含一个节点,该点的字符指向均为空
(2) 插入
插入一个字符串s,令指针p指向根节点,依次扫描s中的字符
1.p指针的c字符指向一个已经存在的节点Q,令p=Q;
2.p指针的c字符指向空,建立一个新节点Q,令p=Q;
3.最后扫描完毕后当前节点指针p上标记的是字符串的末尾
(3)查找
1.p的c字符指针指向空,说明没有插入,结束查询。
2.p的c字符指针指向一个已经存在的节点Q,令p=Q;
3.当指针s中的字符扫描完毕后,若p被标记为一个字符串的末尾则说明Tire已经存在,说明s没有被插入。
例题:
题目描述
原题来自:POJ 3630
给定 nnn 个长度不超过 101010 的数字串,问其中是否存在两个数字串 S,TS,TS,T,使得 SSS 是 TTT 的前缀,多组数据。
输入格式
第一行一个整数 TTT,表示数据组数。
对于每组数据,第一行一个数 nnn,接下来 nnn 行输入 nnn 个数字串。
输出格式
对于每组数据,若存在两个数字串 SSS,TTT,使得 SSS 是 TTT 的前缀,则输出 NO
,否则输出 YES
。
请注意此处结果与输出的对应关系!
样例
样例输入
2
3
911
97625999
91125426
5
113
12340
123440
12345
98346
样例输出
NO
YES
数据范围与提示
对于 100%100\%100% 的数据,1≤T≤40,1≤n≤1041\le T\le 40, 1\le n \le 10^41≤T≤40,1≤n≤104。
#include
#include
#include
using namespace std;
const int N = 100100;
const int Z = 15;
int ch[N][Z],tot,T,n;
bool bo[N];
char s[20];
void Init()
{
memset(ch,0,sizeof(ch));
memset(bo,false,sizeof(bo));
}
bool it(char *s)
{
int len=strlen(s),u=1;
bool fg=false;
for(int i=0;i
补充:
#include
#include
#include
#include
using namespace std;
/*
Tire字典树的存储方法:
构建一个树,每个节点的最多子节点的个数是26(即已知全部单词为小写字母)
1、插入:每次询问一个节点的位置,如果这个位置为空,就为这个位置分配空间,表示此位置存在;
如果此位置已经存在,就沿着这个位置继续查找,直到找到下一个空的位置,重复以上操作;
最后插入完成后统计单词的数量+1;
2、删除 :从根节点开始,如果查找到空节点,说明这个单词不存在,删除失败(就是不用删除)
如果找到,在最后一个单词的结尾位置单词数量-1,表示删除成功
3查找:从根节点开始, 查找没如果节点位置是空,查找失败,不空,并且找完整个字符串,查找成功,返回YES
(注意:最后p都是到单词的最后一个字母,并标记那个字母的状态,如果存在那个字母,即最后一个字母表示一整个单词的状态。)
*/
const int maxn = 26;
struct Node{
int count;
struct Node* next[maxn];
Node(int x):count(x)
{
for(int i=0;inext[val]==NULL) p->next[val] = new Node(0); //新建一个节点,表示新节点的存在,即存储了单词;
p=p->next[val]; //跳转到下一个字母的位置
}
p->count++; //统计单词个数
}
void Delete(Tire &t,string str)
{
int i,l=str.size(),val;
Tire p=t;
for(i=0;inext[val]==NULL) return ;
p=p->next[val];
}
p->count--;
}
bool Search(Tire &t,string str)
{
int i,l=str.size(),val;
Tire p=t;
for(i=0;inext[val]==NULL) return false;
p=p->next[val];
}
return p->count>0;
}
void print(Tire &t,vector > &vc,vector &word)
{
Tire p=t;
if(p==NULL) return ;
if(p->count) vc.push_back(word);
for(int i=0;i<26;i++)
{
if(t->next[i]!=NULL)
{
word.push_back(i+'a');
print(t->next[i],vc,word);
word.pop_back();
}
}
}
/*
int main() {
Tire root = new Node(0);
// 插入
string strs[] = {"ok","applition","app","apple","apply"};
for(int i = 0;i < 5;++i){
Insert(root,strs[i]);
}//for
string str("apple");
cout<<"删除单词["< > words;
vector word;
print(root,words,word);
for(int i = 0;i < words.size();++i){
for(int j = 0;j < words[i].size();++j){
cout<
参考文章:https://blog.csdn.net/sunnyyoona/article/details/43900425