15145641

  字典树较为复杂的应用,我们在建立字典树的过程中需要把所有的前缀都加进去,还需要加一个id,判断它原先是属于哪个串的.有人说是AC自动机的简化,但是AC自动机我还没有做过.

#include<iostream>
#include<string.h>
#include<cstdio>
using namespace std;
char a[22],b[22];
struct Node
{
    int id,num;
    Node *sons[26];
    Node()
    {
        id = -1,num = 0;
        for(int j = 0; j < 26; j++)
            sons[j] = NULL;
    }
};
Node *root;
Node *now,*Next;
void Build(char *str,int len,int nowid)
{
    now = root;
    for(int i = 0; i < len; i++)
    {
        int m = str[i] - 'a';
        if(now->sons[m] == NULL)
        {
            Next = new Node;
            Next->id = nowid;
            Next->num = 1;
            now->sons[m] = Next;
            now = Next;
        }
        else
        {
            now = now->sons[m];
            if(now->id != nowid)
            {
                now->id = nowid;
                now->num++;
            }
        }
    }
}
int Find(char *str,int len)
{
    now = root;
    for(int i = 0; i < len; i++)
    {
        int m = str[i] - 'a';
        if(now->sons[m] == NULL) return 0;
        now = now->sons[m];
    }
    return now->num;
}
void del(Node *root)
{
    for(int i = 0; i < 26; i++)
    {
        if(root->sons[i] != NULL)
            del(root->sons[i]);
    }
    delete root;
}
int main()
{
    int n,m;
    while(~scanf("%d",&n))
    {
        root = new Node;
        for(int i = 1; i <= n; i++)
        {
            scanf("%s",a);
            int lena = strlen(a);
            for(int j = 0; j < lena; j++)
                Build(a+j,lena-j,i);
        }
        scanf("%d",&m);
        for(int i = 1; i <= m; i++)
        {
            scanf("%s",b);
            int lenb = strlen(b);
            printf("%d\n",Find(b,lenb));
        }
        del(root);
    }
    return 0;
}

 

posted on 2016-04-30 21:34  icode-xiaohu  阅读(213)  评论(0编辑  收藏  举报