zoukankan      html  css  js  c++  java
  • hdu-1251 统计难题---字典树

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=1251

    题目大意:

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

     解题思路:
    将每个单词存入字典树中,直接查询前缀出现次数即可,在加入字典树的时候,在每个字母表示的边上后面的节点数加1,记录前缀出现次数。
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<map>
     6 #include<set>
     7 #include<cmath>
     8 #include<algorithm>
     9 #include<vector>
    10 #include<sstream>
    11 #define lowbot(i) (i&(-i))
    12 using namespace std;
    13 
    14 const int maxn = 1e6 + 10;
    15 int tree[maxn][26];
    16 //字典树tree[u][v]表示编号为u的节点的下一个字母为v连接的节点的编号
    17 int idx(char c){ return c - 'a'; }//可以写成宏定义
    18 int tot = 1;//根节点编号为1
    19 int sum[maxn];//标记以该节点结束的前缀出现次数
    20 void Insert(char s[], int u)//u表示根节点
    21 //插入字符串s
    22 {
    23     for(int i = 0; s[i]; i++)
    24     {
    25         int c = idx(s[i]);
    26         if(!tree[u][c])
    27             tree[u][c] = ++tot;
    28         sum[tree[u][c]]++; //前缀后面的那个节点数目加一
    29         u = tree[u][c];
    30     }
    31 }
    32 
    33 int Find_sum(char s[], int u)
    34 {
    35     for(int i = 0; s[i]; i++)
    36     {
    37         int c = idx(s[i]);
    38         if(!tree[u][c])return 0;
    39         u = tree[u][c];
    40     }
    41     return sum[u];//返回最后一个字母表示的边连接的后面那个节点,所记录的sum值
    42 }
    43 int main()
    44 {
    45     char s[15];
    46     while(gets(s) && strlen(s))Insert(s, 1);
    47     while(scanf("%s", s) != EOF)
    48     {
    49         printf("%d
    ", Find_sum(s, 1));
    50     }
    51     return 0;
    52 }
     
  • 相关阅读:
    spark源码阅读之network(2)
    LoadRunner使用问题
    IDEA小技巧:添加代码快捷方式
    ByteUnit
    利用python列出当前目录下的所有文件
    python识别图片中的信息
    2019年3月2日-小雨.md
    2019年3月1日-日记
    2019年2月11日-日记
    2019年2月10日-日记
  • 原文地址:https://www.cnblogs.com/fzl194/p/8951083.html
Copyright © 2011-2022 走看看