poj 2945 trie树统计字符串出现次数

用记录附加信息的val数组记录次数即可。

PS:trie树还有种动态写法,使用指针和动态分配内存代替了连续的ch数组,更加节省内存。

Reference:http://blog.csdn.net/architect19/article/details/8966247

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 using namespace std;
 5 #define maxnode 400010
 6 #define sigma_size 22
 7
 8 char a[maxnode][sigma_size];
 9 int t[maxnode];
10 int n,m;
11 //struct Trie
12 //{
13     int ch[maxnode][sigma_size];        //ch[i][j]:记录结点i的那个编号为j的子节点
14     int val[maxnode];                    //val[i]:i节点的附加信息,
15                                          //若val[i]=0不是还没到单词结束。否则val[i]为该单词的出现次数
16     int sz;
17     void Trie()
18     {
19         sz=1;
20         memset(ch,0,sizeof(ch));
21         memset(val,0,sizeof(val));
22         memset(t,0,sizeof(t));
23     }
24     int idx(char c)                       //idx(c)即字符c的编号。
25     {
26         //A G C T
27         if (c==‘A‘)     return 1;
28         if (c==‘G‘)     return 2;
29         if (c==‘C‘)     return 3;
30         if (c==‘T‘)     return 4;
31         //return c-‘A‘;                    //第一个字符是A
32     }
33     void Insert(char s[sigma_size],int v)
34     {
35         int u=0,n=strlen(s);
36         for (int i=0;i<n;i++)
37         {
38             int c=idx(s[i]);
39             if (!ch[u][c])
40             {
41                 memset(ch[sz],0,sizeof(ch[sz]));
42                 val[sz]=0;
43                 ch[u][c]=sz++;
44             }
45             u=ch[u][c];
46         }
47         //val[u]=v;
48         val[u]+=v;
49     }
50     int Query(char s[sigma_size])     //times of s
51     {
52         int u=0,c;
53         int tm=strlen(s);
54         for (int i=0;i<tm;i++)
55         {
56             //c=s[i]-‘A‘;
57             c=idx(s[i]);
58             if (!ch[u][c])    return 0;
59             u=ch[u][c];
60             //if (val[u]==1)  return true;    //若此时s还没走完但trie树上已经走到结尾了,即树上单词是s的前缀
61         }
62         return val[u];
63     }
64 //};
65
66 int main()
67 {
68     //freopen("in.txt","r",stdin);
69     //ios::sync_with_stdio(false);
70
71     //while (cin>>n>>m)
72     while(~scanf("%d%d",&n,&m))
73     {
74         Trie();
75         if ((n!=0)&&(m!=0))
76         {
77             for (int i=1;i<=n;i++)
78             {
79                 //cin>>a[i];
80                 scanf("%s",a[i]);
81                 Insert(a[i],1);
82             }
83             for (int i=1;i<=n;i++)
84             {
85                 int tm=Query(a[i]);
86                 t[tm]++;
87             }
88             for (int i=1;i<=n;i++)
89                 printf("%d\n",t[i]/i);
90             //cout<<endl;
91         }
92         else break;
93     }
94
95     return 0;
96 }
时间: 2024-10-22 09:35:58

poj 2945 trie树统计字符串出现次数的相关文章

poj 1056 Trie树判断哈夫曼编码是否合法

理解了Trie树然后就能1A   其实估计这个题随便做做就能A掉,可能不需要高级数据. 先贴吉林大学的代码模板 /*==================================================*| Trie树(k叉) | INIT: init(); | 注: tree[i][tk]>0时表示单词存在, 当然也可赋予它更多含义; \*==================================================*/ const int tk = 26,

poj 2503 Trie树

典型的Trie树, 算是复习一下字符串吧, 就是输入有点恶心,代码如下: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 500000+100; struct Trie{ bool isword; int next[26]; char words[15]; Trie(){ memset(next, -1, sizeof(next

Trie树统计单词前缀

输入 输入的第一行为一个正整数n,表示词典的大小,其后n行,每一行一个单词(不保证是英文单词,也有可能是火星文单词哦),单词由不超过10个的小写英文字母组成,可能存在相同的单词,此时应将其视作不同的单词.接下来的一行为一个正整数m,表示小Hi询问的次数,其后m行,每一行一个字符串,该字符串由不超过10个的小写英文字母组成,表示小Hi的一个询问. 输出 对于小Hi的每一个询问,输出一个整数Ans,表示词典中以小Hi给出的字符串为前缀的单词的个数. 样例输入 5 babaab babbbaaaa a

大规模字符串检索-压缩trie树

本文使用压缩trie树实现字符串检索的功能.首先将字符串通过编码转化为二进制串,随后将二进制串插入到trie树中,在插入过程中同时实现压缩的功能. 字符编码采用Huffman,但最终测试发现不采用Huffman的方法不仅省下了编码时间,同时trie树的插入时间也有所减少. 1 /** 2 程序主函数与编码 3 */ 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include &q

B树、Trie树详解

查找(二) 散列表 散列表是普通数组概念的推广.由于对普通数组可以直接寻址,使得能在O(1)时间内访问数组中的任意位置.在散列表中,不是直接把关键字作为数组的下标,而是根据关键字计算出相应的下标. 使用散列的查找算法分为两步.第一步是用散列函数将被查找的键转化为数组的一个索引. 我们需要面对两个或多个键都会散列到相同的索引值的情况.因此,第二步就是一个处理碰撞冲突的过程,由两种经典解决碰撞的方法:拉链法和线性探测法. 散列表是算法在时间和空间上作出权衡的经典例子. 如果没有内存限制,我们可以直接

大数据处理-Trie树

大数据处理--Trie树 1.1.什么是Trie树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高. Trie的核心思想是空间换时间.利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的. 它有3个基本性质: 1. 根节点不包含字符,除根节点外每一个节点都只包含一个字符. 2. 从根节点到某一节点

查找(二)简单清晰的B树、Trie树具体解释

查找(二) 散列表 散列表是普通数组概念的推广.因为对普通数组能够直接寻址,使得能在O(1)时间内訪问数组中的任何位置.在散列表中,不是直接把keyword作为数组的下标,而是依据keyword计算出对应的下标. 使用散列的查找算法分为两步.第一步是用散列函数将被查找的键转化为数组的一个索引. 我们须要面对两个或多个键都会散列到同样的索引值的情况.因此,第二步就是一个处理碰撞冲突的过程,由两种经典解决碰撞的方法:拉链法和线性探測法. 散列表是算法在时间和空间上作出权衡的经典样例. 假设没有内存限

查找(二)简单清晰的B树、Trie树详解

查找(二) 散列表 散列表是普通数组概念的推广.由于对普通数组可以直接寻址,使得能在O(1)时间内访问数组中的任意位置.在散列表中,不是直接把关键字作为数组的下标,而是根据关键字计算出相应的下标. 使用散列的查找算法分为两步.第一步是用散列函数将被查找的键转化为数组的一个索引. 我们需要面对两个或多个键都会散列到相同的索引值的情况.因此,第二步就是一个处理碰撞冲突的过程,由两种经典解决碰撞的方法:拉链法和线性探测法. 散列表是算法在时间和空间上作出权衡的经典例子. 如果没有内存限制,我们可以直接

POJ2513 【并查集+欧拉路径+trie树】

题目链接:http://poj.org/problem?id=2513 Colored Sticks Time Limit: 5000MS   Memory Limit: 128000K Total Submissions:40949   Accepted: 10611 Description You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it