Trie树

链接:https://hihocoder.com/problemset/problem/1014

Input

输入的第一行为一个正整数n,表示词典的大小,其后n行,每一行一个单词(不保证是英文单词,也有可能是火星文单词哦),单词由不超过10个的小写英文字母组成,可能存在相同的单词,此时应将其视作不同的单词。接下来的一行为一个正整数m,表示小Hi询问的次数,其后m行,每一行一个字符串,该字符串由不超过10个的小写英文字母组成,表示小Hi的一个询问。

在20%的数据中n, m<=10,词典的字母表大小<=2.

在60%的数据中n, m<=1000,词典的字母表大小<=5.

在100%的数据中n, m<=100000,词典的字母表大小<=26.

本题按通过的数据量排名哦~

Output

对于小Hi的每一个询问,输出一个整数Ans,表示词典中以小Hi给出的字符串为前缀的单词的个数。

Sample Input

5
babaab
babbbaaaa
abba
aaaaabaa
babaababb
5
babb
baabaaa
bab
bb
bbabbaab

Sample Output

1
0
3
0
0

#include <iostream>
#include <string.h>
#include<cstdio>
using namespace std;
struct Trie{    //字典树定义
    Trie* next[26];
    int num;    //以当前字符串为前缀的单词的数量
    Trie()    //构造函数
    {
        int i;
        for(i=0;i<26;i++){
            next[i] = NULL;
        }
        num=0;
    }
};
Trie root;
void Insert(char word[])    //将字符串word插入到字典树中
{
    Trie *p = &root;
    int i;
    for(i=0;word[i];i++){    //遍历word的每一个字符
        if(p->next[word[i]-'a']==NULL)    //如果该字符没有对应的节点
            p->next[word[i]-'a'] = new Trie;    //创建一个,创建的同时就将该节点的值给赋好了
        p = p->next[word[i]-'a'];//不管p->next[word[i]-'a']是否为空,都要执行这一步,对p进行更新,便于下一步操作
        p->num++;
    }
}
int Find(char word[])    //返回以字符串word为前缀的单词的数量
{
    Trie *p = &root;
    int i;
    for(i=0;word[i];i++){    //在字典树找到该单词的结尾位置
        if(p->next[word[i]-'a']==NULL)
            return 0;
        p = p->next[word[i]-'a'];
    }
    return p->num;
}
int main()
{
    char word[100000][10];
    int n,m;
    scanf("%d",&n);
    for(int i=0;i<n;i++){    //输入单词
        scanf("%s",word[i]);
        Insert(word[i]);
    }
    scanf("%d",&m);
    for(int i=0;i<m;i++){
        scanf("%s",word[i]);
        printf("%d\n",Find(word[i]));    //返回word为前缀的单词的数量
    }
    return 0;
}

 

posted @ 2019-07-12 17:26  里昂静  阅读(125)  评论(0编辑  收藏  举报