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

字典树Trie

时间:2015-04-23 01:52:28      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:

hdu1251

交c++可以过,g++就MLE

技术分享
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
struct Trie{
    Trie *next[26];
    int v;
};
void creatTrie(Trie *root,char *str)
{
    Trie *p=root;
    p=root;
    for(int i=0;str[i];i++)
    {
        int id=str[i]-a;
        if(p->next[id]==NULL)
        {
            Trie *q=new Trie;
            for(int j=0;j<26;j++){
                    q->next[j]=NULL;
            }
            q->v=1;
            p->next[id]=q;
            p=p->next[id];
        }
        else
        {
            p->next[id]->v++;
            p=p->next[id];
        }
    }
}
int findTrie(Trie *root,char *str)
{
    Trie *p=root;
    for(int i=0;str[i];i++)
    {
        int id=str[i]-a;
        if(p->next[id]!=NULL)
            p=p->next[id];
        else return 0;
    }
    return p->v;
}
void Delete(Trie *root)
{
    if(root!=NULL)
    {
        for(int i=0;i<26;i++){
            if(root->next[i]!=NULL)Delete(root->next[i]);
        }
        delete root;
        root=NULL;
    }
}
int main()
{
    Trie *root=new Trie;
    for(int i=0;i<26;i++)root->next[i]=NULL;
    char str[50];
    while(gets(str)&&str[0]!=\0){
            creatTrie(root,str);
    }
    while(gets(str))printf("%d\n",findTrie(root,str));
   // Delete(root);
    return 0;
}
View Code

 

hdu1671

1.有两种情况,一种是前面出现过的串是这个串的前缀,用一个is_end标记来表示前面的串在这里结束

  另一种这个串是前面出现过的串的前缀,直接判断这个串的末尾字符的v是否大于等于2

2.每个case过后要及时释放内存

技术分享
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
#define maxn 10
struct Trie{
    Trie *next[maxn];
    int v;
    bool is_end;
};
int flag;
void Delete(Trie *root)
{
    if(root!=NULL)
    {
        for(int i=0;i<maxn;i++){
            if(root->next[i]!=NULL)Delete(root->next[i]);
        }
        delete root;
        root=NULL;
    }
}
void Clear(Trie *root)
{
    for(int i=0;i<maxn;i++)root->next[i]=NULL;
    root->is_end=false;
}
void creatTrie(Trie *root,char *str)
{
    Trie *p=root;
    p=root;
    for(int i=0;str[i];i++)
    {
        int id=str[i]-0;
        if(p->next[id]==NULL)
        {
            Trie *q=new Trie;
            Clear(q);
            q->v=1;
            p->next[id]=q;
            p=p->next[id];
        }
        else
        {
            p->next[id]->v++;
            p=p->next[id];
            if((p->is_end||str[i+1]==\0)&&p->v>=2)
            {
                flag=0;
            }
         //   printf("** %c %d %d\n",str[i],p->v,p->is_end);
        }
        if(str[i+1]==\0)p->is_end=true;
    }
}
int findTrie(Trie *root,char *str)
{
    Trie *p=root;
    for(int i=0;str[i];i++)
    {
        int id=str[i]-a;
        if(p->next[id]!=NULL)
            p=p->next[id];
        else return 0;
    }
    return p->v;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        char str[50];
        Trie *root=new Trie;
        Clear(root);
        flag=1;
        while(n--)
        {
            scanf("%s",str);
            creatTrie(root,str);
        }
        if(flag)puts("YES");
        else puts("NO");
        Delete(root);
    }
    return 0;
}
/*
2
2
91111
911
2
911
91111

*/
View Code

 

喵星人

此题为了练习字典序特意用findTrie实现了string的find函数功能,可以查找特定字符串(用is_end来标记此处有没有单词的结尾)

并将字典序的代码结构化了一遍,方便修改

技术分享
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 52
struct Trie{
    Trie *next[maxn];
    int v;
    bool is_end;
};
string v[20010];
void Delete(Trie *root)
{
    if(root!=NULL)
    {
        for(int i=0;i<maxn;i++){
            if(root->next[i]!=NULL)Delete(root->next[i]);
        }
        delete root;
        root=NULL;
    }
}
void Clear(Trie *root)
{
    for(int i=0;i<maxn;i++)root->next[i]=NULL;
    root->is_end=false;
}
int charToNum(char s)
{
    if(s>=a&&s<=z)return s-a;
    return s-A+26;
}
void creatTrie(Trie *root,char *str)
{
    Trie *p=root;
    p=root;
    for(int i=0;str[i];i++)
    {
        int id=charToNum(str[i]);
        if(p->next[id]==NULL)
        {
            Trie *q=new Trie;
            Clear(q);
            q->v=1;
            p->next[id]=q;
            p=p->next[id];
        }
        else
        {
            p->next[id]->v++;
            p=p->next[id];
         //   printf("creat %d %d\n",id,p->v);
        }
        if(str[i+1]==\0)p->is_end=true;
    }
}
bool findTrie(Trie *root,string str)
{
    Trie *p=root;
    for(int i=0;i<str.length();i++)
    {
        int id=charToNum(str[i]);

        if(p->next[id]!=NULL){
            p=p->next[id];
       // printf("**%d %d\n",id,p->v);
        }
        else return 0;
    }
    return p->v>=1&&p->is_end;
}

int main()
{
    int n;
    int k=1;
    while(scanf("%d",&n)&&n){
        char str[50];
        Trie *root=new Trie;
        Clear(root);
        for(int i=0;i<n;i++)
        {
            scanf("%s",str);
            v[i]=str;
            creatTrie(root,str);
        }
        sort(v,v+n);
        string str1,str2;
        int flag=1;
        printf("Case #%d:\n",k++);
        for(int i=0;i<n;i++)
        {
            for(int j=1;j<v[i].length();j++)
            {
                str1=v[i].substr(0,j);
                str2=v[i].substr(j);
                if(findTrie(root,str1)&&findTrie(root,str2)){
                    flag=0;
                    printf("%s\n",v[i].c_str());
                    break;
                }
            }
        }
        if(flag)printf("NONE\n");
        printf("\n");
        Delete(root);
    }
    return 0;
}
View Code

 

hdu1247

和上面完全一样,可以作为字典树模板

技术分享
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 52
struct Trie
{
    Trie *next[maxn];
    int v;
    bool is_end;
};
string v[50050];
void Delete(Trie *root)
{
    if(root!=NULL)
    {
        for(int i=0; i<maxn; i++)
        {
            if(root->next[i]!=NULL)Delete(root->next[i]);
        }
        delete root;
        root=NULL;
    }
}
void Clear(Trie *root)
{
    for(int i=0; i<maxn; i++)root->next[i]=NULL;
    root->is_end=false;
}
int charToNum(char s)
{
    if(s>=a&&s<=z)return s-a;
    return s-A+26;
}
void creatTrie(Trie *root,char *str)
{
    Trie *p=root;
    p=root;
    for(int i=0; str[i]; i++)
    {
        int id=charToNum(str[i]);
        if(p->next[id]==NULL)
        {
            Trie *q=new Trie;
            Clear(q);
            q->v=1;
            p->next[id]=q;
            p=p->next[id];
        }
        else
        {
            p->next[id]->v++;
            p=p->next[id];
            //   printf("creat %d %d\n",id,p->v);
        }
        if(str[i+1]==\0)p->is_end=true;
    }
}
bool findTrie(Trie *root,string str)
{
    Trie *p=root;
    for(int i=0; i<str.length(); i++)
    {
        int id=charToNum(str[i]);

        if(p->next[id]!=NULL)
        {
            p=p->next[id];
            // printf("**%d %d\n",id,p->v);
        }
        else return 0;
    }
    return p->v>=1&&p->is_end;
}

int main()
{
    char str[50];
    Trie *root=new Trie;
    Clear(root);
    int n=0;
    while(gets(str))
    {
        v[n++]=str;
        creatTrie(root,str);
    }
    sort(v,v+n);
    string str1,str2;
    int flag=1;
    for(int i=0; i<n; i++)
    {
        for(int j=1; j<v[i].length(); j++)
        {
            str1=v[i].substr(0,j);
            str2=v[i].substr(j);
            if(findTrie(root,str1)&&findTrie(root,str2))
            {
                flag=0;
                printf("%s\n",v[i].c_str());
                break;
            }
        }
    }
    Delete(root);
    return 0;
}
View Code

 一般方法就是直接拿string或者set来做:

技术分享
#include<iostream>
#include<string>
#include<set>
#include<cstdio>
#include<algorithm>
using namespace std;
string v[50050];
int main()
{
    char s[30];
    int n=0;
    while(gets(s))
    {
        v[n++]=s;
    }
    sort(v,v+n);
    string s1,s2;
    bool f=false;
    for(int i=0; i<n; i++)
    {
        for(int j=1; j<v[i].length(); j++)
        {
            s1=v[i].substr(0,j);
            s2=v[i].substr(j);
            if(binary_search(v,v+n,s1)&&binary_search(v,v+n,s2))
            {
                printf("%s\n",v[i].c_str());
                f=true;
                break;
            }
        }
    }
    return 0;
}
View Code

 

参考资料

http://www.cnblogs.com/183zyz/archive/2011/04/28/2031710.html

http://www.cnblogs.com/tanky_woo/archive/2010/09/24/1833717.html

字典树Trie

标签:

原文地址:http://www.cnblogs.com/kylehz/p/4448614.html

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