菜鸟系列——字典树
来源:互联网 发布:淘宝买了假货怎么索赔 编辑:程序博客网 时间:2024/06/06 15:01
做回菜鸟,老老实实重新学起:
字典树
动态模版:
//动态链表实现#define MAXN 26struct node{ node *next[MAXN]; int v; //根据需要变化};node *root;//字典树建立void createTrie(char *str){ int len = strlen(str); node *p = root; for(int i=0; i<len; ++i) { int id = str[i]-'a'; if(p->next[id] == NULL) { p->next[id] = new node(); p->next[id]->v = 1; //初始v==1 for(int j=0; j<MAXN; ++j) p->next[id]->next[j] = NULL; p = p->next[id]; } else { p->next[id]->v++; p = p->next[id]; } }}//查找int findTrie(char *str){ int len = strlen(str); node *p = root; for(int i=0; i<len; ++i) { int id = str[i]-'a'; p = p->next[id]; if(p == NULL) //若为空集,表示不存以此为前缀的串 return 0; } return p->v;//返回以此为前缀的串的数量}//释放空间int dealTrie(node* T){ int i; if(T==NULL) return 0; for(i=0;i<MAXN;i++) { if(T->next[i]!=NULL) dealTrie(T->next[i]); } free(T); return 0;}void solve(int n,int m){ int i,j; char s[101]; root = new node(); root->v = 1; for(j=0; j<MAXN; ++j) root->next[j] = NULL; for(i=0;i<n;i++) { scanf("%s",s); createTrie(s); } for(j=0;j<m;j++) { scanf("%s",s); printf("%d\n",findTrie(s)); }}
静态模版:
//静态数组实现int sum=0,res=0;struct node{ int x,y; int r; int next[26]; void init() { r=0; memset(next,-1,sizeof(next)); }}tree[1000005];void insert_tree(char *str){ int i, j, t; i = j = t = 0; while(str[i]) { t = str[i]-'a'; if(tree[j].next[t] == -1) { tree[sum].init(); tree[j].next[t] = sum++; } j = tree[j].next[t]; tree[j].r++;//记录以此为前缀的单词的数量 i++; }}void query_tree(char *str){ int i,j,t; i = j = t = 0; while(str[i]) { t = str[i]-'a'; if(tree[j].next[t] == -1) { res=0; return; } j=tree[j].next[t]; i++; } res=tree[j].r;//以此为前缀的单词的数量}
eg:
POJ2001 Shortest Prefixes
http://poj.org/problem?id=2001
题意:
求给出字典中每个单词能够被特别的分别出最短前缀;
思路:
字典树模版,遇到小于2的节点停止即可;
code:
#define N 123456s#define MAXN 26char s[N][30];struct node{ node *next[MAXN]; int v; //根据需要变化};node *root;//字典树建立void createTrie(char *str){ int len = strlen(str); node *p = root; for(int i=0; i<len; ++i) { int id = str[i]-'a'; if(p->next[id] == NULL) { p->next[id] = new node(); p->next[id]->v = 1; //初始v==1 for(int j=0; j<MAXN; ++j) p->next[id]->next[j] = NULL; p = p->next[id]; } else { p->next[id]->v++; p = p->next[id]; } }}//查找int findTrie(char *str){ int len = strlen(str); node *p = root; for(int i=0; i<len; ++i) { int id = str[i]-'a'; p = p->next[id]; if(p == NULL) //若为空集,表示不存以此为前缀的串 return 0; printf("%c",str[i]); if(p->v < 2) return 0; } return p->v;//返回以此为前缀的串的数量}//释放空间int dealTrie(node* T){ int i; if(T==NULL) return 0; for(i=0;i<MAXN;i++) { if(T->next[i]!=NULL) dealTrie(T->next[i]); } free(T); return 0;}void solve(){ int i,j; root = new node(); root->v = 1; for(j=0; j<MAXN; ++j) root->next[j] = NULL; i=0; while(scanf("%s",s[i])!=EOF) { createTrie(s[i]); i++; } for(j=0;j<i;j++) { printf("%s ",s[j]); findTrie(s[j]); printf("\n"); }}int main(){ int i,j,k,kk,t,x,y; #ifndef ONLINE_JUDGE freopen("test.txt","r",stdin); #endif solve(); return 0;}
0 0
- 菜鸟系列——字典树
- 菜鸟系列——线段树
- 菜鸟系列——划分树
- 菜鸟系列——最小生成树
- 菜鸟系列——KMP
- 菜鸟系列——搜索
- 菜鸟系列——Sparse Table
- 菜鸟系列——回文串
- 菜鸟系列——最短路
- 菜鸟系列——强连通分量
- 菜鸟系列——二分图匹配
- 菜鸟系列——置换群
- 菜鸟系列——polya计数法
- 菜鸟系列——欧拉函数
- 菜鸟系列——约瑟夫环
- 菜鸟系列——容斥原理
- 菜鸟系列——双连通分量
- 菜鸟系列——康托展开
- Objective-C ---KVO内部实现原理
- 51单片机学习笔记【一】——LED灯实验
- Java使用手机发送短信程序
- 图像扩展函数cvCopyMakeBorder的使用
- Mybatis问题
- 菜鸟系列——字典树
- 整数划分
- 黑马day09 数据库乱码分析
- bzoj1002
- 发发牢骚,觉得走c#这条路,不该太浮躁。
- 机器视觉光源学习总结——高角度环形光源
- 《黑天鹅》观后感
- 细说Cookies
- Visual Studio IDE写C程序