zoukankan      html  css  js  c++  java
  • 字典树入门 统计难题

    统计难题   

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

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


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

    注意:本题只有一组测试数据,处理到文件结束.
     
    Output
    对于每个提问,给出以该字符串为前缀的单词的数量.
     
    Sample Input
    banana band bee absolute acm ba b band abc
     
    Sample Output
    2 3 1 0
     
    字典树:用来查相同前缀的单词书数,第一个是用指针的做法;用指针建树;先是一个空的总根节点,然后是对应26个字母的支,有对应的字母就伸出这个枝,没有就不伸出这个枝;
               它可以根据需要来伸出枝;也可以根据不同的情况有更多的枝;可以加上其他字符和大小写;
                把这些字符用树的方式储存易于查询和删除;求前缀相同的的字符的个数,可以把前缀作为它的根节点,则前缀相同,则根节点相同;在根节点上记录分支的数量;
    则是同一根节点字符串的数量,则是同一前缀字符串的数量;
     
    //用指针的做法;https://blog.csdn.net/qq_36172505/article/details/76887211
    #include<cstdio> #include<cstring> using namespace std; struct node{ node *next[26];//定义26个结构体指针,用来指向可能存在的分支; int cnt;//用于记录该节点分支的数量; node(){//结构体的初始化; cnt=0; memset(next,0,sizeof(next)); } }; node *root=NULL;//定义一个空的结构体指针作为总的根; void buildtree(char *s){//建树; node *p=root;//定义一个结构体指针,先指向root; int l=strlen(s); for(int i=0;i<l;i++){ if(p->next[s[i]-'a']==NULL){//判断该子根是否当前存在; p->next[s[i]-'a']=new node;//不存在就分配一个node型的内存使之存在; } p=p->next[s[i]-'a'];//指针指向该节点,并由该节点向下延伸;同一个字符串在树里也是串在一起的,
    //因此同一个字符串是由根节点一直伸到枝顶,p则是一个动态的指向,表示从哪里开始延伸; p
    ->cnt++;//在一个节点上的一次操作会增加该节点一个分支; } } void findtree(char *s){ node *p=root; int l=strlen(s); for(int i=0;i<l;i++){ if(p->next[s[i]-'a']==NULL){//由上面可以看出所有有效地节点都被分了内存,没有分内存,说明不存在; printf("0 "); return; } p=p->next[s[i]-'a'];//公共整个字符串,要把整个字符串作为根节点; } printf("%d ",p->cnt);//输出该根节点对应的分支; return; } int main(){ char a[15]; root=new node;//为该指针分配空间; while(gets(a)){ if(strcmp(a,"")==0){//判断字符串是否为空; break; }else{ buildtree(a);//将字符串存在树内; } } while(gets(a)){ findtree(a);//查询; } return 0; }
    //数组;https://blog.csdn.net/qq_38891827/article/details/80532462
    #include<cstdio> #include<cstring> using namespace std; const int maxn=2e6+3; int tree[maxn][30];//总的节点数,和每个节点的总的分支数;tree[i][j]表示第i个节点的第j个枝; int sum[maxn];//记录该节点经过的次数,即为分支的个数; int tot;//用于记录节点数; void insert_(char *s){ int len=strlen(s); int root=0; for(int i=0;i<len;i++){ if(tree[root][s[i]-'a']==0){ tree[root][s[i]-'a']=++tot; } sum[tree[root][s[i]-'a']]++; root=tree[root][s[i]-'a']; } return; } int find_(char *s){ int len=strlen(s); int root=0; for(int i=0;i<len;i++){ if(tree[root][s[i]-'a']==0){ return 0; } root=tree[root][s[i]-'a']; } return sum[root]; } int main(){ tot=0; char a[25]; while(gets(a)){ if(strcmp(a,"")==0){ break; } insert_(a); } while(scanf("%s",a)!=EOF){ printf("%d ",find_(a)); } return 0; }
  • 相关阅读:
    096实战 在windows下新建maven项目
    095实战 ETL的数据来源,处理,保存
    094实战 关于js SDK的程序,java SDK的程序
    093实战 Nginx日志切割,以及脚本上传nginx的切割日志
    092实战 数据收集(各种事件)
    091实战 Nginx配置(日志服务器中关于日志的产生)
    android64位机子兼容32位.so库文件
    给 Android 初学者的 Gradle 知识普及
    Android重力感应开发
    随笔之Android平台上的进程调度探讨
  • 原文地址:https://www.cnblogs.com/qqshiacm/p/11181919.html
Copyright © 2011-2022 走看看