码迷,mamicode.com
首页 > 其他好文 > 详细

hdu2846 字典树

时间:2015-08-12 16:35:22      阅读:115      评论:0      收藏:0      [点我收藏+]

标签:

 给你一堆字符串,然后再给你几个查询,前面那些字符串中有多少个包含了这个串。所以可以把开始inset()的字符遍历一遍,同时可能出现该字符串在某个字符串中有多次出现,所以还要用flag标记,来区分不同的串。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct trie
{
    int flag;
    int sum;
    trie *next[26];
};
trie *root;
void init()
{
    int i;
    root=(trie*)malloc(sizeof(trie));
    for(i=0;i<26;i++)
        root->next[i]=NULL;
    root->sum=0;
    root->flag=-1;
}
void insert(char *s,int flag)
{
    trie *q,*p=root;
    int i,j,len=strlen(s);
    for(i=0;i<len;i++)
    {
        int id=s[i]-a;
        if(p->next[id]==NULL)
        {
            q=(trie*)malloc(sizeof(trie));
            for(j=0;j<26;j++)
                q->next[j]=NULL;
            q->sum=0;
            q->flag=-1;
            p->next[id]=q;
        }
        p=p->next[id];
        if(p->flag!=flag)
        {
            p->flag=flag;
            p->sum++;
        }
    }
}
int search(char *s)
{
    int i,j,len=strlen(s);
    trie *p=root;
    for(i=0;i<len;i++)
    {
        int id=s[i]-a;
        if(p->next[id]==NULL)
        {
            return 0;
        }
        p=p->next[id];
    }
    return p->sum;
}
void freetrie(trie *root)
{
    for(int i=0;i<26;i++)
    {
        if(root->next[i])
            freetrie(root->next[i]);
    }
    free(root);
}
int main()
{
    char s[22];
    int i,j,n,q,flag;
    while(scanf("%d",&n)!=EOF)
    {
        init();
        for(i=0;i<n;i++)
        {
            scanf("%s",s);
            int len=strlen(s);
            for(j=0;j<len;j++)
            {
                insert(s+j,i);
            }
        }
        scanf("%d",&q);
        while(q--)
        {
            scanf("%s",s);
            int ans=search(s);
            printf("%d\n",ans);
        }
        freetrie(root);
    }
}

 

hdu2846 字典树

标签:

原文地址:http://www.cnblogs.com/sweat123/p/4724680.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!