• hdu 1251:统计难题[【trie树】||【map】


    <题目链接>

                                           统计难题

    Problem Description
    Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
    Input
    输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.
    注意:本题只有一组测试数据,处理到文件结束.
     
    Output
    对于每个提问,给出以该字符串为前缀的单词的数量.
     
    Sample Input
    banana
    band
    bee
    absolute
    acm
     
    ba
    b
    band
    abc
     
    Sample Output
    2
    3
    1
    0
     
    tire树指针实现:
     1 #include <cstdio>
     2 #include <malloc.h>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 char s[15];
     8 struct node{
     9     int cnt;
    10     node *next[26];  //该节点的所有子节点
    11     void init(){   //初始化该节点
    12         cnt=0;
    13         for(int i=0;i<26;i++)
    14             next[i]=NULL;
    15     }
    16 };
    17 void insert(node *root,char *s){
    18     node *p =root ,*now;
    19     for(int i=0;s[i];i++){
    20         int tmp=s[i]-'a';
    21         if(p->next[tmp]==NULL){   //如果该节点为空,则创建一个新的节点
    22             p->next[tmp]=new node;
    23             p=p->next[tmp];
    24             p->init();
    25         }
    26         else p=p->next[tmp];   //如果该节点不空,则继续向下插入
    27         p->cnt++;    //以该节点结尾的前缀个数+1
    28     }
    29 }
    30 int find(node *root,char *s){
    31     node *p=root;
    32     for(int i=0;s[i];i++){
    33         int tmp=s[i]-'a';
    34         p=p->next[tmp];
    35         if(!p)return 0;   //如果遇到不满足的节点,就直接结束
    36     }
    37     return p->cnt;
    38 }
    39 int main(){
    40     node *root=new node;
    41     root->init();
    42     while(gets(s)&&strlen(s))
    43         insert(root,s);
    44     while(gets(s))
    45         printf("%d
    ",find(root,s));
    46     return 0;
    47 }

    trie树数组实现:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 const int N = 1e6+10;
     7 int trie[N][26];     //trie[now][next]代表第一次遍历到该节点的序号
     8 int num[N]={0},pos=0;
     9 void Insert(char *str){
    10     int now=0;
    11     for(int i=0;str[i];i++){
    12         int next=str[i]-'a';
    13         if(!trie[now][next])trie[now][next]=++pos;  //如果没有遍历过该节点,就给该节点赋值(相当于给trie树创建一个节点)
    14         now=trie[now][next];     
    15         num[now]++;    //该前缀的数量+1
    16     }
    17 }
    18 int Search(char *str){
    19     int now=0;
    20     for(int i=0;str[i];i++){
    21         int next=str[i]-'a';
    22         if(!trie[now][next])return 0;   //只要一找到不符合的节点,就直接返回0
    23         now=trie[now][next];   //当前节点继续向下匹配
    24     }
    25     return num[now];
    26 }
    27 int main(){
    28     char str[15];
    29     while(gets(str)&&strlen(str))
    30         Insert(str);
    31     while(gets(str))
    32         printf("%d
    ",Search(str));
    33     return 0;
    34 }

    map做法

    #include <cstdio>
    #include <string>
    #include <map>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    
    int main()
    {
        string s, str[10000];
        int cur = 0;
        map<string, int>mapp;
        while (getline(cin, s) && s[0] != '')    //注意是用这个来判断空行,首先一定要用getline读入,其次是s[0]==''时表示是空行
        {
            string ss;
            for (int i = 1; i <=s.length(); i++) {
                ss = s.substr(0, i);         //获得字符串s中从第0位开始的长度为i的字符串
                mapp[ss]++;
            }
        }
        while (cin >> s)
        {
            printf("%d
    ", mapp[s]);
        }
        return 0;
    }
     
    2018-04-08
  • 相关阅读:
    常见的位运算技巧总结(膜wys)
    BZOJ1878:[SDOI2009]HH的项链
    BZOJ4300:绝世好题
    BZOJ1298:[SCOI2009]骰子的学问
    BZOJ2748:[HAOI2012]音量调节
    BZOJ1951:[SDOI2010]古代猪文
    BZOJ1002:[FJOI2007]轮状病毒
    BZOJ1081:[SCOI2005]超级格雷码
    BZOJ2595:[WC2008]游览计划
    BZOJ1190:[HNOI2007]梦幻岛宝石
  • 原文地址:https://www.cnblogs.com/00isok/p/8736794.html
Copyright © 2020-2023  润新知