字典树模板

来源:互联网 发布:黑客编程入门3pdf 编辑:程序博客网 时间:2024/05/22 13:36

一、

HDU1671(统计是否有相同前缀):

代码如下:

#include <cstdio>#include <cstring>#include <malloc.h>#include <iostream>using namespace std;#define MAXN 10typedef struct Trie{    int v;//根据需要变化    Trie *next[MAXN];    //next是表示每层有多少种类的数,如果只是小写字母,则26即可,    //若改为大小写字母,则是52,若再加上数字,则是62了}Trie;Trie* root;void createTrie(char *str){    int len = strlen(str);    Trie *p = root, *q;    for(int i = 0; i < len; i++)    {        int id = str[i]-'0';        if(p->next[id] == NULL)        {            q = (Trie *)malloc(sizeof(Trie));            q->v = 1;//初始v==1            for(int j = 0; j < MAXN; j++)                q->next[j] = NULL;            p->next[id] = q;            p = p->next[id];        }        else        {        //    p->next[id]->v++;            p = p->next[id];        }    }     p->v = -1;//若为结尾,则将v改成-1表示}int findTrie(char *str){    int len = strlen(str);    Trie *p = root;    for(int i = 0; i < len; i++)    {        int id = str[i]-'0';        p = p->next[id];        if(p == NULL) //若为空集,表示不存以此为前缀的串            return 0;        if(p->v == -1)   //字符集中已有串是此串的前缀            return -1;    }    //return p->v;    return -1;   //此串是字符集中某串的前缀}int dealTrie(Trie* T){    //动态字典树,有时会超内存,这是就要记得释放空间了    if(T==NULL)        return 0;    for(int i = 0; i < MAXN; i++)    {        if(T->next[i]!=NULL)            dealTrie(T->next[i]);    }    free(T);    return 0;}int main(){    int t, n;    char str[15];    scanf("%d",&t);    while(t--)    {        int flag = 0;        root = (Trie *)malloc(sizeof(Trie));        for(int i = 0; i < MAXN; i++)            root->next[i] = NULL;        scanf("%d",&n);        for(int i = 0; i < n; i++)        {            scanf("%s",str);            if(findTrie(str) == -1)            {                flag = 1;                continue;            }            createTrie(str);        }        if(flag)            printf("NO\n");        else            printf("YES\n");        dealTrie(root);    }    return 0;}



二、

HDU 1251(统计相同前缀的数量):

代码如下:

#include <cstdio>#include <cstring>#include <malloc.h>#include <iostream>using namespace std;#define MAXN 26typedef struct Trie{    int v;//根据需要变化    Trie *next[MAXN];    //next是表示每层有多少种类的数,如果只是小写字母,则26即可,    //若改为大小写字母,则是52,若再加上数字,则是62了}Trie;Trie *root;void createTrie(char *str){    int len = strlen(str);    Trie *p = root, *q;    for(int i = 0; i < len; i++)    {        int id = str[i]-'a';        if(p->next[id] == NULL)        {            q = (Trie *)malloc(sizeof(Trie));            q->v = 1;//初始v==1            for(int j = 0; j < MAXN; j++)                q->next[j] = NULL;            p->next[id] = q;            p = p->next[id];        }        else        {            p->next[id]->v++;            p = p->next[id];        }    }    // p->v = -1;//若为结尾,则将v改成-1表示}int findTrie(char *str){    int len = strlen(str);    Trie *p = root;    for(int i = 0; i < len; i++)    {        int id = str[i]-'a';        p = p->next[id];        if(p == NULL) //若为空集,表示不存以此为前缀的串            return 0;      //  if(p->v == -1)   //字符集中已有串是此串的前缀      //      return -1;    }    return p->v;    //return -1;   //此串是字符集中某串的前缀}int dealTrie(Trie* T){    //动态字典树,有时会超内存,这时就要记得释放空间了    if(T==NULL)        return 0;    for(int i = 0; i < MAXN; i++)    {        if(T->next[i]!=NULL)            dealTrie(T->next[i]);    }    free(T);    return 0;}int main(){    char str[15];    root = (Trie *)malloc(sizeof(Trie));    for(int i = 0; i < MAXN; i++)        root->next[i] = NULL;    while(gets(str) && str[0]!='\0')        createTrie(str);    memset(str, 0, sizeof(str));    while(scanf("%s", str) != EOF)    {        int ans = findTrie(str);        printf("%d\n", ans);    }    return 0;}


2 0