字典树

字典树模板。。

半城伤御伤魂 提交于 2020-03-05 00:17:19
无聊弄个字典树的模板。自己一直不是很懂字典树。。可能要学数据结构之后自己再深究一下。。这个比较重要。。 前缀: #include <iostream> #include <string> #include <algorithm> using namespace std; #define MAXS 26 #define MAXL 22 #define MAXN 1005 char str[MAXN][MAXL]; struct node { int num;//num表示用到该节点的字符串的个数,num=1时说明该节点是该字符串唯一的节点 node *next[MAXS]; node() { num=0; for(int i=0;i<MAXS;i++) { next[i]=NULL; } } }*root; void insert(node *rt,char *str) { int i,id,len; len=strlen(str); for(i=0;i<len;i++) { id=str[i]-'a'; if(rt->next[id]==NULL) rt->next[id]=new node(); rt=rt->next[id]; rt->num++; } } void serch(node *rt,char *s) { int i,id,len; len=strlen(s);

单词的前缀 字典树

谁说我不能喝 提交于 2020-03-05 00:16:43
单词的前缀 Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other) Total Submission(s) : 167 Accepted Submission(s) : 46 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description ZZY 针对某个单词表给单词定义了特别的前缀,该前缀使得在该表中可以唯一标识某个单词,并且前缀的长度是最短。若有单词是另一个单词的前缀,那么该单词的前缀就是其本身。 Input 输入包含多组数据,对于每组数据,第一行是整数 N(1~1000) ,表示单词表中单词的个数,接下来是 N 行,分别表示一个单词,每个单词长度不超过 20 位,并且都是小写字母组成。 Output 对每组输入,输出 2 行,第一行输出 “***Case 组号 ” ,接下按之前的单词表顺序,输出 N 行,每行由单词表中的单词和前缀组成,中间用空格隔开 . Sample Input 1 a 10 lap njzatz jhjn ousua j lhdahl gtmz xxisug tv aho Sample Output ***Case 1 a a ***Case 2 lap la

hdu1305Immediate Decodability(字典树)

浪子不回头ぞ 提交于 2020-03-04 23:37:37
这题看是否 这题能A是侥幸,解决的办法是先存一下输入的字符串,进行排序。 Problem Description An encoding of a set of symbols is said to be immediately decodable if no code for one symbol is the prefix of a code for another symbol. We will assume for this problem that all codes are in binary, that no two codes within a set of codes are the same, that each code has at least one bit and no more than ten bits, and that each set has at least two codes and no more than eight. Examples: Assume an alphabet that has symbols {A, B, C, D} The following code is immediately decodable: A:01 B:10 C:0010 D:0000 but this one is not: A:01 B:10 C

01字典树

余生长醉 提交于 2020-03-02 01:14:06
学习与: https://blog.csdn.net/zuzhiang/article/details/79872805 一.描述 1.与普通字典树相似,只不过不是插入字符,而是 插入二进制串的每一位(0或1) 2.01字典树是一棵 最多32层的二叉树 3.tree[i] 表示一个节点, tree[i][0] 和 tree[i][1] 表示节点的两条边指向的节点,val[i] 表示节点的值。 4.每个节点主要有 4个属性: 节点值、节点编号、两条边指向的下一节点的编号。 5.节点值 val为 0 时表示到当前节点为止 不能形成一个数,否则 val[i]=数值。 6.可通过贪心的策略来寻找 与x异或结果最大(最小)的数 ,即 优先找和x的二进制的未处理的最高位值不同(相同)的边对应的点 ,这样保证结果最大。 二.模板 int tot = 0 ; ll val [ 32 * maxn ] ; int tree [ 32 * maxn ] [ 2 ] ; void init ( ) { //初始化 tot = 0 ; memset ( tree , 0 , sizeof ( tree ) ) ; memset ( val , 0 , sizeof ( val ) ) ; } void insertt ( ll num ) //插入 { int root = 0 ; for ( int i

js实现字典树

房东的猫 提交于 2020-02-29 09:48:18
function Node(){ this.next=[] this.value= '' }//字典树和链表的区别,是next指向一个node 和 node[]的区别 function RTree(){ this.root = new Node(); this.put = (key,value)=>{ return _put(this.root, key ,value,0) } this.get = (key)=>{ let res = _get(this.root, key, 0) if(res === null || res === undefined){ return null} return res.value } this.contains = (key)=>{ let res = this.get(key) console.log('get 返回了',res) if(res !== null && res !== undefined ){ return true } return false } function _put (x,key,val,i) { //如果不存在,初始化 if(x=== null || x === undefined){ x = new Node(); } //如果找到了,更新或者写入它储存的值 if(i== key.length){ x

hdu 5269 ZYB loves Xor I(字典树)

淺唱寂寞╮ 提交于 2020-02-28 06:44:04
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5269 思路分析: 当lowbit(AxorB)=2 p 时,表示A与B的二进制表示的0-p-1位相等,第p位不同; 考虑维护一棵字母树,将所有数字 转换为二进制形式并且从第0位开始插入树中,并在每个节点中记录通过该结点的数字数目; 最后统计答案,对于每一个数字, 对于在其路径中的每一个结点X,假设其为第K层,统计通过与该结点不同的值的结点的数目count,则结果增加count*2 k ; 代码如下: #include <cstdio> #include <cstring> #include <iostream> using namespace std; const int MAX_N = 5 * 10000 + 100; int num[MAX_N]; struct Node{ Node *child[2]; int count; Node(){ count = 0; memset(child, 0, sizeof(child)); } Node(int value){ count = value; memset(child, 0, sizeof(child)); } }; void Insert(Node *head, int value){ Node *pre = head,

hdu3460(字典树)

别来无恙 提交于 2020-02-28 04:36:42
http://acm.hdu.edu.cn/showproblem.php?pid=3460 题意:一开始没有明白题意,看了好久,才明白,原来它是将一个单词打印出来后再在打印机里面删除字母,也就是说,如果单词前缀相同,则只需删除单词不相同的部分,再插入下一个单词不相同的部分。这样的话,可以用字典树,要是单词前缀相同,则在字典树上只有一个结点,那么,要是将最长的那个单词也删除了,则是对字典树上的结点插入一次再删除一次,还要输出n次,也就是2*numnode+n;但是最长的那个单词len不需要删除,则是2*numnode+n-len; #include<iostream> #include<cstring> using namespace std; typedef struct tree { int num; tree *next[26]; }tree; tree *root; int count; void creat(char str[]) { int len=strlen(str); tree *p=root,*q; for(int i=0;i<len;i++) { int x=str[i]-'a'; if(p->next[x]) { p->next[x]->num++; p=p->next[x]; } else { q=(tree *)malloc(sizeof(tree));

01字典树(删除与添加操作)

风流意气都作罢 提交于 2020-02-28 04:33:59
http://acm.hdu.edu.cn/showproblem.php?pid=5536 题意:在一个数组中找出 (s[i]+s[j])^s[k] 最大的值,其中 i、j、k 各不相同。 题解:1、可直接暴力O(n 3 ) 2、01字典树可以在数组中找到一个数与X异或和最大和其异或结果。本题中的X是数组中的两个不同的数的和,在数组中找另一个与前两个数不同的异或和最大。为了确保找到数与前两个数不同,所有要进行删除与添加操作。另开一个数组记录节点访问次数,通过对访问次数的加减进行删除与添加操作。 https://blog.csdn.net/zuzhiang/article/details/79872805 #include <bits/stdc++.h> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <string> #include <stdio.h> #include <queue> #include <stack> #include <map> #include <set> #include <string.h> #include <vector> #define ME(x , y) memset(x , y ,

算法导论:Trie字典树

a 夏天 提交于 2020-02-23 15:13:45
1、 概述 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树。 Trie一词来自re trie ve,发音为/tri:/ “tree”,也有人读为/traɪ/ “try”。 Trie树可以利用字符串的公共前缀来节约存储空间。如下图所示,该trie树用10个节点保存了6个字符串pool、prize、preview、prepare、produce、progress 在该trie树中,字符串preview,prepare公共前缀是“pre”,因此可以只存储一份“pre”以节省空间。当然,如果系统中存在大量字符串且这些字符串基本没有公共前缀,则相应的trie树将非常消耗内存,这也是trie树的一个缺点。 Trie树的基本性质可以归纳为: (1)根结点不包含字符,除根节点意外每个结点只包含一个字符。 (2)从根结点到某一个结点,路径上经过的字符连接起来,为该结点对应的字符串。 (3)每个结点的所有子结点包含的字符串不相同。 注意:每个结点可以有没有或者一个或者多个字结点,叶子结点没有子结点 2、数据结构表示 /** * 定义字典树的数据结构 * c 当前节点值 * isLeaf 是否是叶子结点 * children 孩子,key是孩子结点值,value是孩子结点的下一个字典树 * */ class

sdut 字典树

时光总嘲笑我的痴心妄想 提交于 2020-02-17 19:11:22
字典树 Description 遇到单词不认识怎么办? 查字典啊,已知字典中有n个单词,假设单词都是由小写字母组成。现有m个不认识的单词,询问这m个单词是否出现在字典中。 Input 含有多组测试用例。 第一行输入n,m (n>=0&&n<=100000&&m>=0&&m<=100000)分别是字典中存在的n个单词和要查询的m个单词. 紧跟着n行,代表字典中存在的单词。 然后m行,要查询的m个单词 n=0&&m=0 程序结束 数据保证所有的单词都是有小写字母组成,并且长度不超过10 Output 若存在则输出Yes,不存在输出No . Sample Input 3 2 aab aa ad ac ad 0 0 Output No Yes 等有空再补充链表的做法 #include <bits/stdc++.h> using namespace std; char s[20]; int trie[500010][26]; //数组开的很玄学,大一点TLE小一点RTE int cc[500010]; //用来证明单词存在 int f = 1; void in_sert(){ int k = strlen(s); int p = 0; for(int i = 0; i<k; i++){ int c = s[i] - 'a'; if(!trie[p][c]){ memset(trie[f],