如果可以,可以陪你千年不老,千年只想眷顾你倾城一笑;如果愿意,愿意陪你永世不离,永世只愿留恋你青丝白衣。
首先什么是trie树呢?
Trie树也叫字典树,是一种树形结构,专门用于处理在一个字符串集合中查找某个字符串。
那trie树在我们实际应用中有哪些例子呢?
其实trie树这种数据结构,应用十分常见,比如所我们的搜索引擎就是利用了这一个功能,要知道数据库是十分庞大的,从里面查找一个内容效率并不是很高,而利用trie树这一结构可以很快地通过关键词查到,而且还会出现一系列相关的词条。
平常使用的百度搜索:
淘宝购物:
trie在算法上有什么作用呢?
(1)查询某个字符串是否出现过
(2)查询某个前缀是否出现过
(3)查询某个单词出现过几次或者某个前缀出现过几次(你只需要在建树的时候用book数组记录一下出现次数就可以了)。
说了那么多那trie树到底长什么样儿呢?
例如:需要在how,him,hi,hello,so,see这六个字符串中查找某个字符串,那我们就可以建个下面的trie树:
那这样就行了吗?比如我们要查询hi,会发现him的前缀中也包含hi,所以我们要在每一个字符串的结尾加入一个结束符。
构造过程也是将字符桉树连接起来就行,上面的图中很明显有一个不包含任何信息的根节点。
所以,利用代码实现是怎样的呢?
实现查询某个字符串是否出现过
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <ctime>
#include <cctype>
#include <bitset>
#include <utility>
#include <sstream>
#include <complex>
#include <iomanip>
#define inf 0x3f3f3f3f
typedef long long ll;
using namespace std;
const int maxn=1e3;
int trie[maxn][maxn],book[maxn];
int tot=0;
void init()
{
memset(trie,0,sizeof(trie));
memset(book,0,sizeof(book));
tot=0;
}
void build(string s)
{
int u=0;
for(int i=0; i<s.size(); i++)
{
int c=s[i]-'a';
if(trie[u][c]==0)
trie[u][c]=++tot;
u=trie[u][c];
}
book[u]=1;
}
int query(string s)
{
int len=s.size();
int u=0;
for(int i=0; i<len; i++)
{
if(trie[u][s[i]-'a']==0)
return 0;
u=trie[u][s[i]-'a'];
}
if(book[u])
return 1;
}
int main()
{
int n;
string s;
init();
cin>>n;
getchar();
while(n--)
{
cin>>s;
build(s);
}
cin>>s;
cout<<query(s)<<endl;
return 0;
}
实现查询某个前缀是否出现过
int query(string s)
{
int len=s.size();
int u=0;
for(int i=0;i<len;i++)
{
if(trie[u][s[i]-'a']==0)
{
return 0;
}
u=trie[u][s[i]-'a'];
}
return 1;
}
那trie树的缺点是什么呢?
trie树虽然节省了时间,但是却是消耗了空间,是用空间换时间的一种数据结构。