Trie字典树
说到这个应该都不陌生,也许你知道他是什么样的,但用代码实现就有一些生疏!
上面就是一个Trie字典树,一般用于实现以下等功能
1.字符串检索
2.词频统计
3.字符串排序
4.前缀匹配
5.最大异或对/最大异或值
Trie原理就是一棵树,用来存储字符串或者二进制,因为其原理与某些问题的解决有天然优势,因此在了解其原理后,我们用代码将其实现!
trie数组表示构建一个trie,num[]可用于表示每个前缀中含有的个数 或者 可用于表示每个字符串结束的位置个数!
const int N= 1e6 + 10 ;
int trie[ N] [ 26 ] ;
int num= [ N] = { 0 } ;
接下来是Insert()函数,用于实现trie的插入和删除,插入和删除取决与输入的v;p表示每次插入的下标为p!
通过循环插入字符串,如果trie前缀为出现,则trie[p][n]为pos,不然就是前缀相同,当输入的字符串结束后,num[p]++操作用于储存结束标志!
int pos= 1 ;
string s;
void Insert ( int v) {
int p= 0 ;
for ( int i= 0 ; i< s. size ( ) ; i++ ) {
int n= s[ i] - 'a' ;
if ( trie[ p] [ n] == 0 )
trie[ p] [ n] = pos++ ;
p= trie[ p] [ n] ;
num[ p] += v;
}
}
插入操作理解后,Find()查询操作就类似了,通过判断一个新的字符串是否在遍历trie过程中有前缀或是是前缀!
int Find ( ) {
int p= 0 ;
for ( int i= 0 ; i< s. size ( ) ; i++ ) {
int n= s[ i] - 'a' ;
if ( trie[ p] [ n] == 0 )
return 0 ;
p= trie[ p] [ n] ;
}
return num[ p] ;
}
最终代码如下:
# include <bits/stdc++.h>
using namespace std;
const int N= 1e6 + 10 ;
int trie[ N] [ 26 ] ;
int num= [ N] = { 0 } ;
int pos= 1 ;
string s;
void Insert ( int v) {
int p= 0 ;
for ( int i= 0 ; i< s. size ( ) ; i++ ) {
int n= s[ i] - 'a' ;
if ( trie[ p] [ n] == 0 )
trie[ p] [ n] = pos++ ;
p= trie[ p] [ n] ;
num[ p] += v;
}
}
int Find ( ) {
int p= 0 ;
for ( int i= 0 ; i< s. size ( ) ; i++ ) {
int n= s[ i] - 'a' ;
if ( trie[ p] [ n] == 0 )
return 0 ;
p= trie[ p] [ n] ;
}
return num[ p] ;
}
int main ( ) {
return 0 ;
}
这是模板的代码,稍加改变可以实现很多功能,最主要还是要理解其中的意思,以后就可以得心应手了!