trie树 和 树的存储--左儿子右兄弟 --- uva 11732
来源:互联网 发布:福瑞博德软件开发 编辑:程序博客网 时间:2024/05/17 23:48
trie树也叫前缀树 , 是一种字符串的快速查找树 , 有就是一种树。
因为trie树 , 是一种树 ,因此我们先讨论树的存储。
树的存储:左儿子右兄弟
对于普通情况下的树 , 我们会采用儿子节点法 , 来存储 , 但在trie中 , 往往采用左儿子右兄弟的存储法 , 更为快速。
左儿子右兄弟就是说,在树中 , 每个结点有两个指针结点 , 一个指向其儿子 , 一个指向其兄弟。
一下的代码 , 我们是用数组来代替链表的 , 这样更方便。
代码:
#include <iostream>#include <stdio.h>using namespace std;#define maxn 100struct node{char y;int next ; //儿子int right; //兄弟//void clear1() {next = -1 ; right = -1;}}trie[maxn];int next = 1;char ch[maxn];void init(){trie[0].next = trie[0].right = -1;}void insert(){int u = 0 , v;int i , j;bool flag;for(i = 0; ch[i] ; i++){flag = false;for(v = trie[u].next ; v != -1; v = trie[v].right){if(trie[v].y == ch[i]){flag = true;break;}}if(!flag){ v = next++;trie[v].right = trie[u].next;trie[u].next = v; trie[v].next = -1;trie[v].y = ch[i];}u = v;}}int main(){return 0;}
uva11732解法:
这个题目一看就知道是用trie树, 来存储每个单词 , 然后每加入一个单词 , 我们就计算需要计算多少次 , 这样就能得到总的次数。然后当我们用普通的树存储方法时 , 就肯定会超时 , 因此需要使用 左儿子右兄弟的存储法。
比较是:
1、两个相同字符 2次
2、两个不同字符 1次
3、'/0' 和 '/0' 2次
4、'/0' 和其他字符 1次
代码:
#include <iostream>#include <stdio.h>#include <string.h>using namespace std;#define maxn 4000010struct node{char y; int son; //指向儿子int right; //指向右边的兄弟节点 int sum ; //表示有多少个儿子}trie[maxn];int ch[123];char str[1010];int n , trie_s ;long long sum ;void init(){trie[0].son = trie[0].right = -1;trie[0].sum = 0;sum = 0;trie_s = 1;}void insert1(){ int i , j , k = strlen(str); //int x , y = 0; int u = 0;bool flag; for(i = 0; i <= k ; i++) {flag = false;for(j = trie[u].son ; j != -1 ; j = trie[j].right){if(trie[j].y == str[i]){flag = true;break;}}if(!flag){j = trie_s++;trie[j].right = trie[u].son;trie[j].y = str[i];trie[u].son = j;//trie[u].sum += 1; //记录有多少儿子trie[j].sum = 0;trie[j].son = -1;} if(i == k) { sum += trie[u].sum+trie[j].sum; trie[j].sum++;} //特判结尾 Trie中不会进入结尾字符,需特判统计 else sum += (trie[u].sum+trie[j].sum); trie[u].sum++; u = j; //trie[u].sum += 1; //记录有多少儿子//sum += trie[u].sum+trie[j].sum-1;//u = j; } //sum += trie[u].sum+trie[u].p*2;//trie[u].p += 1;}int main(){ int cas = 1; int i ; while(scanf("%d" , &n) && n) {init(); for(i = 1; i <= n; i++) { scanf("%s" , str); insert1(); } cout<<"Case "<<cas++<<": "; cout<<sum<<endl;//printf("%I64d\n" , sum); } return 0;}/*2ab4cathatmatsir0*/
0 0
- trie树 和 树的存储--左儿子右兄弟 --- uva 11732
- UVA 11732 "strcmp()" Anyone? Trie树 + 树的左儿子右兄弟存储法
- Uva 11732 "strcmp()" Anyone? 左儿子右兄弟的trie
- UVa 11732 strcmp函数 trie树 左儿子右兄弟表示法
- UVA 11732 strcmp() Anyone?(左儿子右兄弟Trie)
- UVA 11732("strcmp()" Anyone?-Trie与左兄弟右儿子)
- 左儿子右兄弟Trie UVA 11732 strcmp() Anyone?
- UVA 11732 strcmp() Anyone? Trie的左儿子右兄弟表示法
- UVA - 11732 依旧是字典树板子,和左儿子右兄弟法字典树
- uva 11732 "strcmp()" Anyone? (trie+左儿子右兄弟表示法)
- UVA 11732-"strcmp()" Anyone?-trie(左儿子右兄弟表示法(省空间))
- (uva 11732) "strcmp()" Anyone? (trie+左儿子右兄弟表示法)
- UVA11732 左儿子右兄弟 Trie
- UVA 11732 "strcmp()" Anyone(字典树+左儿子-右兄弟表示法)
- 树的左儿子右兄弟表示法
- UVA 11732 strcmp() Anyone 左兄弟右孩子Trie
- UVA 11732 —— 左儿子右兄弟表示法&&Tire
- 左孩子右兄弟的字典树
- MFC 单文档窗口最大化显示
- C++类成员函数中static变量小测试
- 更改git clone时默认检出的分支
- 自定义security过滤器顺序
- CentOS 6.5搭建本地yum源的两种方式链接
- trie树 和 树的存储--左儿子右兄弟 --- uva 11732
- android 单元测试
- Oracle 分析函数及开窗函数 解析
- 深入学习Make命令和Makefile(上)(4)
- 在线程中执行带参数的委托
- 点点网创始人的创业理念
- C语言高效编程的四大秘技之以空间换时间
- 类的自动类型转换和强制类型转换
- 深入学习Make命令和Makefile(下)(1)