zoukankan      html  css  js  c++  java
  • hdu 1251(字典树)(3种方法)

    统计难题

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


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

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

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

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

    Sample Input
    banana band bee absolute acm ba b band abc
     

    Sample Output
    2 3 1 0
      

           这个题就是建立普通的字典树,首先读入单词,建立树,然后每行一个询问,输出以这个询问为前缀的单词数量(若单词本身就是前缀,那么这个单词也要计数)。

          处理数据时注意:1.以一空行作为单词输入结束.

                                     2.若用静态数组的方法建树,数组要开大点,比如500000,开小了就是runtime error


    第一种方法:静态数组法

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    const int MAX=26;
    const int MAXN=500000;
    int  tree[MAXN][MAX];
    int   val[MAXN];
    int node;
    void Insert(char s[])
    {
        int i,tmp;
        int rt=0;
        for(i=0; s[i]; i++)
        {
            tmp=s[i]-'a';
            if(tree[rt][tmp]==0)
            {
                tree[rt][tmp]=++node;
            }
            rt=tree[rt][tmp];
            val[rt]++;
        }
    }
    int Search(char s[])
    {
        int rt=0;
        int i=0,tmp;
        while(s[i])
        {
            tmp=s[i]-'a';
            i++;
            if(tree[rt][tmp]==0)return 0;
            rt=tree[rt][tmp];
        }
        return val[rt];
    }
    int main()
    {
        int i;
        node=0;
        char str[22];
        memset(val,0,sizeof(val));
        memset(tree,0,sizeof(tree));
          while(gets(str),strcmp(str,""))
         Insert(str);
         while (gets(str))
         {
            printf("%d
    ", Search(str));
         }
         return 0;
    }

    第二种方法:指针法建树

    #include<string.h>
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    struct node
    {
        bool is;
        int cnt;
        node *next[27];
        node()
        {
            is=false;
            cnt=0;
            memset(next,0,sizeof(next));
        }
    };
    void Insert(node *rt,char s[])
    {
        node *p=rt,*newnode;
        int i=0,tmp;
        int ok=1;
        for(i=0; i<strlen(s); i++)
        {
            tmp=s[i]-'a';
            if(p->next[tmp]==NULL)
            {
                newnode=new node();
                p->next[tmp]=newnode;
            }
            p=p->next[tmp];
            p->cnt++;
        }
        p->is=true ;
    }
    int Search(node *rt,char s[])
    {
        node *p=rt;
        int i=0,tmp;
        for(i=0; i<strlen(s); i++)
        {
            tmp=s[i]-'a';
            if(p->next[tmp]==NULL)return 0;
            p=p->next[tmp];
        }
        return p->cnt;
    }
    
    int main()
    {
        int i=0;
        node *rt=new node();
           char str[20];
        while(gets(str),strcmp(str,""))
        Insert(rt,str);
        while(gets(str)!=NULL)
        printf("%d
    ",Search(rt,str));
        return 0;
    
    }

    第三种方法:可以使用map的方法(看别的网友代码时发现的)

    #include <cstdio>
    #include <iostream>
    #include <map>
    #include <cstring>
    #include <string>
    using namespace std;
    
    int main()
    {
    	char str[17];
    	map<string, int> m;
    	while(gets(str))
    	{
    		int len = strlen(str);
    		if (!len)
    		{
    			break;
    		}
    		for(int i = len; i > 0; i--)
    		{
    			str[i] = '';
    			m[str]++;
    		}
    	}
    	while(gets(str))
    	{
    		cout<<m[str]<<endl;
    	}
    
    	return 0;
    }
    



  • 相关阅读:
    MySQL——字符串拆分(含分隔符的字符串截取)
    一列数据组合成字符串并用逗号隔开
    web最大化,最小化文字错位的问题
    Esxi虚拟机安装Ros+Openwrt软路由双系统简单分享(踩到的坑,很大的坑)
    跟着老司机免费申请一个域名去!
    logging模块
    os.rename 和os.replace
    装饰器详解
    python if not
    globals和locals的区别
  • 原文地址:https://www.cnblogs.com/hjch0708/p/7554846.html
Copyright © 2011-2022 走看看