传说中的字典树,来学习一下
实现字符串快速检索的多叉树结构
基本操作过程
1.初始化
一个空Trie仅包含一个根节点,该点的字符指针为空
2.插入
当需要插入一个字符串S时,令一个指针P起初指向根节点,然后依次扫描S中的每个字符c
1)若P的c字符指针指向一个已经存在的节点Q,则令P=Q;
2)若P的c字符指针为空,则新建一个节点Q,令P的c字符指针指向Q,然后令P=Q;
当S中的字符扫描完毕,在当前节点P上标记它是一个字符串的末尾//?
3.检索
当需要检索一个字符串S在Trie中是否存在,我们令一个指针P起初指向根节点,然后依次扫描S中的每个字符c:
1)若P的c字符指针指向一个已经存在的节点Q,则令P=Q;
2)若P的c字符指针为空,说明S没有被插入过,结束检索;
当S的字符扫描完毕,若当前节点P被标记为一个字符串末尾,则说明S在Trie中存在。否则,不存在。
下给出插入检索代码:
int trie[SIZE][26],tot=1;//初始化,假设每个字符都是小写字母 void insert(char *str){//插入 int len =strlen(str),p=1; for(int k=0;k<len;k++){ int ch=str[k]-'a'; if(trie[p][ch]==0)trie[p][ch]=++tot;//tot定位下一个字母位置 p=trie[p][ch]; } end[p]=true; } bool search(char *str)//检索 { int len=strlen(str),p=1; for(int k=0;k<len;k++){ p=trie[p][str[k]-'a']; if(p==0)return false; } return end[p]; }
#include<bits/stdc++.h> using namespace std; #define SIZE 1000010 int trie[SIZE][26]; int tot=1; int ed[SIZE]; int ans=0; void insert(char *s) { int len=strlen(s); int p=1; for(int i=0;i<len;i++){ if(trie[p][s[i]-'a']==0){ trie[p][s[i]-'a']=++tot; } p=trie[p][s[i]-'a']; } ed[p]++; } void search(char *s) { int len=strlen(s); int p=1; for(int i=0;i<len;i++){ if(trie[p][s[i]-'a']==0){ return; } p=trie[p][s[i]-'a']; ans+=ed[p]; } //ans+=end[p]; } char s[1000010]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i=0;i<n;i++){ scanf("%s",s); insert(s); } for(int i=0;i<m;i++){ scanf("%s",s); ans=0; search(s); cout<<ans<<' '; } }
沿与Ai当前位置相反的字符指针向下访问
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll A[100005]; ll ed[4200005]; int B[4200005][2]; int tot=1; int F[32]; void div(ll x) { int i=0; while(x){ if(x&1){ F[i]=1; } else F[i]=0; x>>=1; i++; } while(i<32){ F[i]=0; i++; } } void insert(ll x) { int p=1; div(x); for(int i=0;i<32;i++){ if(!B[p][F[31-i]]){ B[p][F[31-i]]=++tot; } p=B[p][F[31-i]]; } ed[p]=x; } ll search(ll x) { int p=1; div(x); for(int i=0;i<32;i++){ if(B[p][!F[31-i]]){ p=B[p][!F[31-i]]; } else p=B[p][F[31-i]]; } return x^ed[p]; } int main() { int n; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%lld",&A[i]); insert(A[i]); } ll ans; for(int i=0;i<n;i++){ if(i==0)ans=search(A[0]); else ans=max(ans,search(A[i])); } cout<<ans<<' '; }