字典树(trie树)是一种根据前缀在log(n)左右时间内完成查询的数据结构。
可以添加辅助数组来完成特定功能。
插入:
int trie[MAXN][50],sum[MAXN];//sum记录单词出现的次数 char buf[MAXN][50]; int tot;//给节点编号 void insert(char str[]) { int root=0; for(int i=0;str[i];i++) { int id=str[i]-'a'; if(!trie[root][id]) trie[root][id]=++tot;//如果没有这个前缀,就扩展一个节点,给这个节点编号 root=trie[root][id];//移到下一个节点 } sum[root]++; }
查询:
int query(char str[]) { int root=0; for(int i=0;str[i];i++) { int id=str[i]-'a'; if(!trie[root][id]) return 0; root=trie[root][id]; } return sum[root]; }
例题:HDU - 1247
划分字符串。
#include<stdio.h> #include<math.h> #include<string.h> #include<algorithm> using namespace std; #define MAXN 50005 int trie[MAXN][50],sum[MAXN];//sum记录单词出现的次数 char buf[MAXN][50]; int tot;//给节点编号 void insert(char str[]) { int root=0; for(int i=0;str[i];i++) { int id=str[i]-'a'; if(!trie[root][id]) trie[root][id]=++tot;//如果没有这个前缀,就扩展一个节点,给这个节点编号 root=trie[root][id];//移到下一个节点 } sum[root]++; } int query(char str[]) { int root=0; for(int i=0;str[i];i++) { int id=str[i]-'a'; if(!trie[root][id]) return 0; root=trie[root][id]; } return sum[root]; } int main() { char str[50]; tot=0; memset(trie,0,sizeof trie); memset(sum,0,sizeof sum); int cnt=0; while(~scanf("%s",buf[cnt])) insert(buf[cnt++]); char c1[100],c2[100]; for(int i=0;i<cnt;i++) { int len=strlen(buf[i]); for(int j=0;j<len-1;j++) { memcpy(c1,buf[i],sizeof c1); memcpy(c2,buf[i]+j+1,sizeof c2); c1[j+1]=0; if(query(c1) && query(c2)) { puts(buf[i]); break; } } } return 0; }