trie树模板(统计难题)

统计难题

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)
Total Submission(s): 36675    Accepted Submission(s):
13637

Problem Description

Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).

Input

输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.

注意:本题只有一组测试数据,处理到文件结束.

Output

对于每个提问,给出以该字符串为前缀的单词的数量.

Sample Input

banana
band
bee
absolute
acm

ba
b
band
abc

Sample Output

2
3
1
0

Author

Ignatius.L

点一下查找树的要点:

1.根节点是个空点,只有形式上的起点作用(插入、查找时从它开始)

2.熟练应用指针,才能避免过多的调试

指针型

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node{
    int k;bool ift;
    node *ch[26];
}*root;
node *create()
{
    node *d=new(node);
    memset(d->ch,0,sizeof(d->ch));
    d->k=0;
    d->ift=0;
    return d;
}
void insert(char *s)
{
    node *q=root;
    char *p=s;
    while(*p)
    {
        int id=*p-‘a‘;
        if(q->ch[id]==NULL)q->ch[id]=create();
        q=q->ch[id];
        p++;
        q->k++;
    }
    q->ift=1;
}
int search(char *s)
{
    node *q=root;
    char *p=s;
    while(*p)
    {
        int id=*p-‘a‘;
        q=q->ch[id];
        p++;
        if(q==NULL)return 0;
    }
    return q->k;
}
int main()
{
    root=create();char s[12];
    bool r=0;
    while(gets(s))
    {
        if(strlen(s)==0)break;
        insert(s);
    }
    while(gets(s))cout<<search(s)<<endl;
}

数组模拟

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int trie[400001][26],len,root,tot,sum[400001];
bool p;
char s[11];
void insert()
{
    len=strlen(s);
    root=0;
    for(int i=0;i<len;i++)
    {
        int id=s[i]-‘a‘;
        if(!trie[root][id]) trie[root][id]=++tot;
        sum[trie[root][id]]++;
        root=trie[root][id];
    }
}
int search()
{
    root=0;
    len=strlen(s);
    for(int i=0;i<len;i++)
    {
        int id=s[i]-‘a‘;
        if(!trie[root][id]) return 0;
        root=trie[root][id];
    }
    return sum[root];
}
int main()
{
    while(gets(s))
    {
        if(!p)
        {
            if(strlen(s)) insert();
            else p=1;
        }
        else printf("%d\n",search());
    }
}

时间: 2024-08-07 21:48:10

trie树模板(统计难题)的相关文章

HDU 1251 Trie树模板题

1.HDU 1251 统计难题  Trie树模板题,或者map 2.总结:用C++过了,G++就爆内存.. 题意:查找给定前缀的单词数量. #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<cstdio> #define max(a,b) a>b?a:b #define F(i,a,b

poj3630 Phone List (trie树模板题)

Phone List Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 26328   Accepted: 7938 Description Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let's say the phone catalogu

Trie树 模板

typedef struct node { int count; struct node *next[MAX]; }Trie; Trie *Newnode()//建立结点&初始化a { int i; Trie *T; T = (Trie *)malloc(sizeof(Trie)); T->count = 0; for(i=0;i<MAX;i++) T->next[i] = NULL; return T; } void creatTrie(Trie *root, char *st

hdu 4828 Xor Sum (trie 树模板题,经典应用)

hdu 4825 题目链接 题意:给定n个数,然后给出m个询问,每组询问一个数x,问n中的数y使得x和y的异或和最大. 思路:字典树..把每个数转化成二进制,注意补全前导0,使得所有数都有相同的位数. 如果想要异或和最大,那么每一位尽可能都是1. 所以做法是,先构建字典树,然后每次find的时候,尽可能按照和当前寻找的数的位相反的位的方向走(如果有的话) 比如当前位是1,那我就往0的方向走. 需要注意的是,多组数据,每次要重新初始化一遍. 做法是 在struct 中重新 root = new N

835. 字符串统计(Trie树模板题)

维护一个字符串集合,支持两种操作: “I x”向集合中插入一个字符串x: “Q x”询问一个字符串在集合中出现了多少次. 共有N个操作,输入的字符串总长度不超过 105105,字符串仅包含小写英文字母. 输入格式 第一行包含整数N,表示操作数. 接下来N行,每行包含一个操作指令,指令为”I x”或”Q x”中的一种. 输出格式 对于每个询问指令”Q x”,都要输出一个整数作为结果,表示x在集合中出现的次数. 每个结果占一行. 数据范围 1≤N≤2∗1041≤N≤2∗104 输入样例: 5 I a

(trie)HDU1251 统计难题

Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串. 注意:本题只有一组测试数据,处理到文件结束. Output对于每个提问,给出以该字符串为前缀的单词的数量. Sa

8.10 trie树模板

字典树是一种很简单的数据结构,就是将字符串存在书上,相同前缀进行压缩 模板题:http://acm.hdu.edu.cn/showproblem.php?pid=1251 #include<bits/stdc++.h> #define fi first #define se second #define rep( i ,x ,y ) for( int i= x; i<= y ;i++ ) #define reb( i ,y ,x ) for( int i= y; i>= x ;i-

Trie树模板例题

一.模板 结构体 struct Trie{ int val; Trie *nex[26]; Trie(){ val = 0; for(int i = 0; i < 26; ++i) nex[i] = NULL; } }; 建树 void build(string x, Trie *root){ int len = x.size(); for(int i = 0; i < len; ++i){ int cur = x[i] - 'a'; if(root -> nex[cur] == NUL

【字典树】统计难题

Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串. 注意:本题只有一组测试数据,处理到文件结束.Output对于每个提问,给出以该字符串为前缀的单词的数量.Samp