zoukankan      html  css  js  c++  java
  • HDU-1251 统计难题 (Trie)

    题目:

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

    Input

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

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

    Output

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

    Sample Input

    banana
    band
    bee
    absolute
    acm

    ba
    b
    band
    abc

    Sample Output

    2
    3
    1
    0


    思路:

    • Trie字典树模板题,我用了两种做法,一种是指针写的,一种是汪神传授的数组模拟,数组一开始过不去问学长说数组要开大一点。
    • 数组模拟Trie有一点我想了很久才明白,就是ch[1][x]只记录每个串第一个位置的下标,相当于一个入口,如果要标记或者计数是不考虑它的。
    • 这题提交要用C++,G++会MLE。

    链式Trie代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 #include<set>
     8 
     9 using namespace std;
    10 
    11 typedef struct TrieNode{
    12     int cnt;
    13     bool flag;
    14     TrieNode *next[26];
    15     TrieNode(){
    16         cnt = 0;
    17         flag = false;
    18         memset(next, 0, sizeof(next));
    19     }
    20 }TrieNode, *Trie;
    21 
    22 TrieNode *InitTrieNode(){
    23     TrieNode *p = new TrieNode;
    24     return p;
    25 }
    26 
    27 void InsertNode(Trie root, char *word){
    28     Trie p = root;
    29     char *ch = word;
    30     int id;
    31     while(*ch){
    32         id = *ch - 'a';
    33         if (p->next[id] == NULL)
    34             p->next[id] = InitTrieNode();
    35         p = p->next[id];
    36         p->cnt++;
    37         ++ch;
    38     }
    39     p->flag = true;
    40 }
    41 
    42 int TrieSearch(Trie root, char *word){
    43     Trie p = root;
    44     char *ch = word;
    45     int id;
    46     bool ans = false;
    47     while(*ch){
    48         id = *ch - 'a';
    49         if (p->next[id] == NULL)
    50             return 0;
    51         p = p->next[id];
    52         ++ch;
    53     }
    54     return p->cnt;
    55 }
    56 
    57 int main()
    58 {
    59     Trie root = InitTrieNode();
    60     char ch[15], c;
    61     while(gets(ch), ch[0]){
    62         InsertNode(root, ch);
    63     }
    64     while(scanf("%s", &ch) != EOF){
    65         printf("%d
    ", TrieSearch(root, ch));
    66     }
    67 
    68     return 0;
    69 }

    数组模拟Trie代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 #include<set>
     8 
     9 using namespace std;
    10 int ch[1100000][26], cnt[1100000], fir[26], num = 1;
    11 
    12 void Insert(char *word){
    13     int now = 1, len = strlen(word), id;
    14     for (int i = 0; i < len; ++i){
    15         id = word[i] - 'a';
    16         if (ch[now][id]) now = ch[now][id];
    17         else now = ch[now][id] = ++num;
    18         ++cnt[now];
    19     }
    20 }
    21 
    22 int Search(char *pre){
    23     int len = strlen(pre), now = 1, id;
    24     for (int i = 0; i < len; ++i){
    25         id = pre[i] - 'a';
    26         if (ch[now][id]) now = ch[now][id];
    27         else return 0;
    28     }
    29     return cnt[now];
    30 }
    31 
    32 int main()
    33 {
    34     char word[20], c;
    35     while(gets(word), word[0]){
    36         Insert(word);
    37     }
    38     while(scanf("%s", &word) != EOF){
    39         printf("%d
    ", Search(word));
    40     }
    41 
    42     return 0;
    43 }
  • 相关阅读:
    SQL2008-表对表直接复制数据
    delphi debug release区别是什么?
    javascript中的for in循环和for in循环的使用陷阱
    JS操作DOM节点大全
    JS中for循环里面的闭包问题的原因及解决办法
    使用sessionStorage、localStorage存储数组与对象
    JS中substr和substring的用法和区别
    HBuilder使用夜神模拟器调试Android应用
    JSON.parse()和JSON.stringify()
    url中的特殊符号含义
  • 原文地址:https://www.cnblogs.com/robin1998/p/6359123.html
Copyright © 2011-2022 走看看