• 统计难题


    统计难题

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


    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
     
    Recommend
    Ignatius.L
    /*
    模板题只需要在树上加一个数组表示以节点i为前缀的单词的数量
    */
    #include<bits/stdc++.h>
    #define MAX 26
    #define N 12
    using namespace std;
    const int maxnode=4000*100+100;///预计字典树最大节点数目
    const int sigma_size=26;///每个节点的最多儿子数
    
    struct Trie
    {
        ///这里ch用vector<26元素的数组> ch;实现的话,可以做到动态内存
        int ch[maxnode][sigma_size];///ch[i][j]==k表示第i个节点的第j个儿子是节点k
        int val[maxnode];///val[i]==x表示第i个节点的权值为x
        int sz;///字典树一共有sz个节点,从0到sz-1标号
        int v[maxnode];///v[i]表示以i为前缀的单词有多少
    
        ///初始化
        void Clear()
        {
            sz=1;
            memset(ch[0],0,sizeof(ch[0]));///ch值为0表示没有儿子
            memset(v,0,sizeof v);
        }
    
        ///返回字符c应该对应的儿子编号
        int idx(char c)
        {
            return c-'a';
        }
    
        ///在字典树中插入单词s,但是如果已经存在s单词会重复插入且覆盖权值
        ///所以执行Insert前需要判断一下是否已经存在s单词了
        void Insert(char *s)
        {
            int u=0,n=strlen(s);
            for(int i=0;i<n;i++)
            {
                int id=idx(s[i]);
                if(ch[u][id]==0)///无该儿子
                {
                    ch[u][id]=sz;
                    memset(ch[sz],0,sizeof(ch[sz]));
                    val[sz++]=0;
                }
                u=ch[u][id];
                v[u]++;
            }
            val[u]=n;///在单词的末尾做一个标记就是这个字母的长度
        }
    
        ///在字典树中查找单词s
        int Search(char *s)
        {
            int n=strlen(s);
            int u=0;///u表示的是当前遍历到哪个节点了,最开始实在root节点
            for(int i=0;i<n;i++)
            {
                int id=idx(s[i]);
                if(ch[u][id]==0)
                    return 0;
                u=ch[u][id];///将遍历的节点放到下一个上
            }
            return v[u];
        }
    };
    Trie trie;///定义一个字典树
    char ch[N];
    char op[N];
    int main()
    {
        //freopen("C:\Users\acer\Desktop\in.txt","r",stdin);
        trie.Clear();
        while(gets(ch))
        {
            //cout<<ch<<endl;
            if(strcmp(ch,"")==0)///空行为停止的条件
                break;
            trie.Insert(ch);
        }
        while(gets(op))
        {
            //cout<<op<<endl;
            printf("%d
    ",trie.Search(op));
        }
        return 0;
    }
  • 相关阅读:
    几种常见的基于Lucene的开源搜索解决方案对比
    【例子】Bobobrowse:lucene分组统计扩展组件
    Solr 相似页面MoreLikeThis
    eclipse安装、基本使用、常用设置
    iPhone开发入门守则:ObjectiveC编码规范系列教程
    ios开发学习按钮(Button)效果源码分享
    ios开发学习音频声效(Audio)效果源码分享系列教程
    ios开发学习动画(Animation)效果源码分享系列教程1
    ios开发学习图表(Chart)效果源码分享系列教程
    局网满猿关不住,一波码农出墙来。
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/6005727.html
Copyright © 2020-2023  润新知