美文网首页
字典树模板(非原创)

字典树模板(非原创)

作者: 四川孙一峰 | 来源:发表于2017-04-17 20:48 被阅读0次

    动态版本

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cstdlib>
    using namespace std;
    const int maxn = 15;
    int ans;
    char num[10000];
    
    
    struct Trie{
        struct Trie* next[maxn];
        bool flag;
    };
    
    struct Trie* root;
    
    struct Trie* Creat_Trie(){
        struct Trie* temp = (struct Trie*)malloc( sizeof(struct Trie) );
        for(int i = 0 ; i < 10 ; i++){
            temp -> next[i] = NULL;
        }
        temp -> flag = false;
        return temp;
    }
    
    void del(Trie *rt){         //Delete重名
         if(!rt) return;
         for(int i = 0 ; i < 10 ; i++){
            if(rt->next[i]) del(rt->next[i]);
         }
         free(rt);
    }
    
    void Insert(char* s){
        int len = strlen(s);
        struct Trie* temp = root;
        bool ff = false;
        for(int i = 0 ; i < len ; i++){
            //printf("i = %d\n",i);
            int k = s[i] - '0';
            if( temp -> next[k] ){
                if(!temp -> flag && i == len - 1){    //当前字符串为其他字符串的子串。
                    ans++;
                    ff = true;
                }
                temp = temp -> next[k];
                if( i == len - 1 ) temp -> flag = true;
                if(ff) return ;
            }
            else{
                if(temp -> flag){   //说明找到这里已经有某个串是该串的子串了,不需要向下创建。
                    ans = true;
                    return;
                }
                else{
                    temp -> next[k] = Creat_Trie();
                    temp = temp -> next[k];
                    if(i == len - 1) temp -> flag = true;  //如果该串已经到了结尾,那么对应的尾节点flag 正确代表一个字符串,
                    else temp -> flag = false;
                }
            }
        }
    }
    
    
    int main(){
        int cas;
        cin >> cas;
        while(cas--){
            int n;
            ans = false;
            cin >> n;
            root = Creat_Trie();
            while(n--){
                cin >> num;
                Insert(num);
            }
            del(root);
            if(!ans) cout << "YES" << endl;
            else cout << "NO" << endl;
        }
    }
    
    

    静态版本(更快)

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <algorithm>
    #include <string.h>
    #include <iostream>
    using namespace std;
    #define LL long long
    #define CLR(x) memset(x, 0, sizeof(x))
    struct Trie{
        int cnt;
        Trie *next[26];
    };
    Trie Merrory[1000000];
    int ant;
    Trie *Create()
    {
        Trie *rt;
        rt = &Merrory[ant++];
        rt->cnt = 1;
        for (int i = 0; i < 26; i++)
            rt->next[i] = NULL;
        return rt;
    }
    
    void Insert(char *s, Trie *Prt)
    {
        Trie *p;
        if(!(p = Prt)) p = Prt = Create();      //括号里面只要能有一个等号嘛= =
    
        int i = 0, k;
        while(s[i])
        {
            k = s[i++] - 'a';
            if(p->next[k]) p->next[k]->cnt++;
            else p->next[k] = Create();
    
            p = p->next[k];
        }
    }
    
    int Search(char *s, Trie *rt)
    {
        if (!rt) return 0;
        Trie *tmp = rt;
        int i = 0, k;
        while(s[i])
        {
            int k = s[i] - 'a';
            if (tmp->next[k]) tmp = tmp->next[k];
            else return 0;
            i++;
        }
        return tmp->cnt;
    }
    
    int main()
    {
        char s[12]={0};
        Trie *rt = Create();
        while(gets(s) && s[0]!='\0')
        {
            Insert(s, rt);
        }
        while(gets(s))
        {
            int res = Search(s, rt);
            printf("%d\n", res);
        }
        return 0;
    }
    
    

    相关文章

      网友评论

          本文标题:字典树模板(非原创)

          本文链接:https://www.haomeiwen.com/subject/eykxzttx.html