sdut 字典树

字典树

Time Limit: 1000 ms Memory Limit: 65536 KiB

Submit Statistic

Problem Description

遇到单词不认识怎么办? 查字典啊,已知字典中有n个单词,假设单词都是由小写字母组成。现有m个不认识的单词,询问这m个单词是否出现在字典中。

Input

含有多组测试用例。

第一行输入n,m (n>=0&&n<=100000&&m>=0&&m<=100000)分别是字典中存在的n个单词和要查询的m个单词.

紧跟着n行,代表字典中存在的单词。

然后m行,要查询的m个单词

n=0&&m=0 程序结束

数据保证所有的单词都是有小写字母组成,并且长度不超过10

Output

若存在则输出Yes,不存在输出No .

Sample Input

3 2
aab
aa
ad
ac
ad
0 0

Sample Output

No
Yes

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct node
{
    int data; 
    int next[26];          //0-25对应a-z,也是记录本字母的指向的空间,代表字典中有这个单词的这个字母
} a[1000000];             //a相当于一个个的节点,从0开始一个一个增加,
int top;                  //top 相当于创建节点的p一样,创建一个个节点
int kong()
{
    memset(a[top].next,-1,sizeof(a[top].next));   
    a[top].data=0;
    top++;                //节点移动
    return top-1;          //返回上一个创造的那个节点的坐标
}
void insert(int root,char s[])     //进行插入,就是创造一个字典,这里的root一直都是0
{
    int i,t;
    for(i=0; s[i]; i++)           
    {
        t=s[i]-'a';               //使0-25与a-z对应
        if(a[root].next[t]==-1)a[root].next[t]=kong();      //如果=-1说明这个单词的这个字母在字典中没有
        root=a[root].next[t];        //那么就进行存储这个单词的这个字母,kong返回的是一个空间的地址
    }                              //既a的一个下标,然后移动root,使它指向这个单词的这个字母,然后
    a[root].data++;//判断下一个字母之前是否存在,最后记录这个单词的这个字母,让它++,看看这个单词出现
}                           //几次
int judge(int root,char s[])
{
    int i,t;
    for(i=0; s[i]; i++)
    {            
        t=s[i]-'a';                   
        if(a[root].next[t]==-1)return 0;   //如果等于-1说明这个单词的这个字母字典中没有,那么这个单词就
        root=a[root].next[t];         //没有,返回0,如果有进行判断下一个字母
    }
    return a[root].data; //直到判断完全部字母,然后返回最后一个字母的次数
}
int main()
{
    int n,m;
    char s[12];
    int root;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        top=0;
        if(n==0&&m==0)break;
        int i;
        root=kong();           //先弄一个空间,root=0;
        for(i=0; i<n; i++)
        {
            scanf("%s",s); 
            insert(root,s);  //这里的root一直为0
        }
        for(i=0; i<m; i++)
        {
            scanf("%s",s);
            if(judge(root,s))printf("Yes\n");  
            else printf("No\n");
        }
    }
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值