字典树hdu1251

统计难题

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

 

Input

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

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

 

Output

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

 

Sample Input

banana

band

bee

absolute

acm

 

ba

b

band

abc

 

Sample Output

2

3

1

0

法一:

#include<iostream>

#include<string.h>

#include<stdio.h>

#include<stdlib.h>

#definemaxn 26

usingnamespace std;

typedefstruct TrieNode

{

    int num;

    struct TrieNode *next[maxn];

}Trie;

voidinsert(Trie *root,char *str){

    if(root==NULL||*str=='\0'){

        return;

    }

    Trie *p=root;

    while(*str!='\0')

    {

        if(p->next[*str-'a']==NULL)

        {

            Trie*temp=(Trie*)malloc(sizeof(Trie));

           temp->num=1;

           for(int i=0;i<maxn;i++)

           {

               temp->next[i]=NULL;

           }

           p->next[*str-'a']=temp;

           p=p->next[*str-'a'];

        }

        else

        {

            p->next[*str-'a']->num++;

            p=p->next[*str-'a'];

        }

        str++;

    }

}

intsearch(Trie *root,char *str)

{

    Trie *p=root;

    for(int i=0;i<strlen(str);i++)

    {

        p=p->next[str[i]-'a'];

        if(p==NULL)

        {

            return 0;

            }

    }

    return p->num;

}

voiddel(Trie *root)

{

    for(int i=0;i<maxn;i++)

    {

        if(root->next[i]!=NULL)

        del(root->next[i]);

    }

    free(root);

}

intmain()

{

    char str[15];

    memset(str,0,sizeof(str));

    Trie *root=(Trie*)malloc(sizeof(Trie));

    for(int i=0;i<maxn;i++)

   {

     root->next[i]=NULL;

   }

   while(gets(str)&&str[0])

   {

       insert(root,str);

   }

   while(gets(str)&&str[0])

   {

       printf("%d\n",search(root,str));

   }

   del(root);

    return 0;

}

法二:#include <iostream>

#include <stdio.h>

using namespace std;

char qiu[20];

int maxl=0;

class trie

{

public:

    trie*next[26];

    int num;//记录前缀的个数

    char*color;

    bool value;//标记这里是不是一个单词

    trie()

    {

        for(int i=0; i<26; i++)

            next[i]=0;

        color=NULL;

        value=0;

        num=0;

    }

} root;

void insert(trie*p,char*s)

{

    int k=0;

    while(s[k]!='\0')

    {

        if(!p->next[s[k]-'a'])

                p->next[s[k]-'a']=new trie;

                p=p->next[s[k]-'a'];

                p->num++;

                k++;

    }

p->value=1;

}

int find(char *s)

{

    trie*p=&root;

    int k=0;

   while(s[k]!='\0'&&p->next[s[k]-'a'])

    {

        p=p->next[s[k]-'a'];

        k++;

    }

    if(s[k]=='\0')

    return p->num;

       return 0;

}

int main()

{

    char eng[12],m[12];

   trie *p=&root;

   while(gets(eng)&&eng[0]!='\0')

   {

       insert(p,eng);

   }

   while(scanf("%s",m)!=EOF)

    cout<<find(m)<<endl;

}

你可能感兴趣的:(字典树)