zoukankan      html  css  js  c++  java
  • Trie

    写过一篇字典树的详解+模版

    http://www.cnblogs.com/grubbyskyer/p/3843243.html


    ZOJ 1109 Language of Fatmouse

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=109

    用map完全能水过,不过还是练一下手...

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<iostream>
     5 #define MAXN 26
     6 using namespace std;
     7 typedef struct Trie
     8 {
     9   Trie *next[MAXN];
    10   char word[10];
    11 }Trie;
    12 
    13 Trie root;
    14 
    15 void createTrie(char *str, char* str1)
    16 {
    17   Trie *p = &root, *q;
    18   for (int i = 0; i < strlen(str); ++i)
    19   {
    20     int id = str[i] - 'a';
    21     if (p->next[id] == NULL)
    22     {
    23       q = (Trie*)malloc(sizeof(Trie));
    24       
    25       for (int i = 0; i < MAXN; ++i)
    26       {
    27         q->next[i] = NULL;
    28       }
    29       p->next[id] = q;
    30       p = p->next[id];
    31     }else
    32     {
    33       p = p->next[id];
    34     }
    35   }
    36   strcpy(p->word, str1);
    37 }
    38 
    39 string findTrie(char *str)
    40 {
    41   Trie *p = &root;
    42 
    43   for (int i = 0; i < strlen(str); ++i)
    44   {
    45     int id = str[i] - 'a';
    46     if (p->next[id] == NULL)
    47     {
    48         string s = "eh";
    49       
    50       return s;
    51     }else
    52     {
    53       p = p->next[id];
    54     }
    55   }
    56 
    57   return p->word;
    58 }
    59 
    60 int main()
    61 {
    62   char line[25];
    63 //  string word;
    64   char word[10];
    65   char dic[10];
    66   int a = 0;
    67   char op;
    68   string ans;
    69   while(1)
    70   {
    71     op = cin.peek();
    72     if(op == '
    ')
    73     {
    74       cin.get();
    75       op = cin.peek();
    76       if(op == '
    ')
    77       {
    78         cin.get();
    79         break;
    80       }
    81     }    
    82     scanf("%s", &word);;
    83     scanf("%s", &dic);
    84 //    word = hah;
    85     createTrie(dic, word);
    86   }
    87   while(scanf("%s", dic) != EOF)
    88   {
    89     ans = findTrie(dic);
    90     cout << ans <<endl;
    91   }
    92   return 0;
    93 }
    View Code

    COJ 1216 异或最大值

    http://122.207.68.93/OnlineJudge/problem.php?id=1216

    COJ 1323 ZZY and his little friends

    http://122.207.68.93/OnlineJudge/problem.php?id=1323

    这两道题都是在n个数中求任两个数异或的最大值,考虑将每个数字的二进制01串建成Trie,

    和它异或最大的必是按照贪心原则每次选择和它不一样的串得到的数(如果存在的话 0选1 1选0)

    最后遍历一边数组对每个数都求一个异或的最大值,其中最大的就是答案,具体见代码吧...

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #define MAXN 100005
      4 int a[MAXN];
      5 int str[31];
      6 typedef struct Trie
      7 {
      8     Trie *next[2];
      9     int v;
     10 }Trie;
     11 Trie *root;
     12 void createTrie(int x)
     13 {
     14     int k=1;
     15     for(int i=30;i>=0;i--)//得到01串
     16     {
     17         if((k<<i)&x)
     18         {
     19             str[30-i]=1;
     20         }else
     21         {
     22             str[30-i]=0;
     23         }
     24     }
     25     Trie *p=root,*q;
     26     for(int i=0;i<31;i++)
     27     {
     28         int id=str[i];
     29         if(p->next[id]==NULL)
     30         {
     31             q=(Trie*)malloc(sizeof(Trie));
     32             for(int j=0;j<2;j++)
     33             {
     34                 q->next[j]=NULL;
     35             }
     36             q->v=0;
     37             p->next[id]=q;
     38         }
     39         p=p->next[id];
     40     }
     41     p->v=x;//在最后的结点里保存上这个数的十进制值,便于等下查找时候取异或
     42 }
     43 int findMax(int x)
     44 {
     45     int k=1;
     46     for(int i=30;i>=0;i--)
     47     {
     48         if((k<<i)&x)
     49         {
     50             str[30-i]=1;
     51         }else
     52         {
     53             str[30-i]=0;
     54         }
     55     }
     56     Trie *p=root;
     57     for(int i=0;i<31;i++)
     58     {
     59         int id=str[i];
     60         if(p->next[(id+1)%2]!=NULL)//贪心的往下选 0选1 1选0
     61         {
     62             p=p->next[(id+1)%2];
     63         }else//不存在的话没办法了 0还是0 1还是1
     64         {
     65             p=p->next[id];
     66         }
     67     }
     68     return x^(p->v);//返回x与此数的异或值  这个数就是整个数组中与x异或最大的那个
     69 }
     70 int delTrie(Trie *T)
     71 {
     72     if(T==NULL)
     73     {
     74         return 0;
     75     }else
     76     {
     77         for(int i=0;i<2;i++)
     78         {
     79             if(T->next[i]!=NULL)
     80             {
     81                 delTrie(T->next[i]);
     82             }
     83         }
     84     }
     85     free(T);
     86     return 0;
     87 }
     88 int main()
     89 {
     90     int n;
     91     while(~scanf("%d",&n))
     92     {
     93     int max=0;
     94     root=(Trie*)malloc(sizeof(Trie));
     95     for(int i = 0; i < 2; i++)
     96     {
     97       root->next[i] = NULL;
     98     }
     99     for(int i=0;i<n;i++)
    100     {
    101         scanf("%d", &a[i]);
    102         createTrie(a[i]);
    103     }
    104     for(int i=0;i<n;i++)
    105     {
    106         if(findMax(a[i])>max)
    107         {
    108             max=findMax(a[i]);
    109         }
    110     }
    111     printf("%d
    ",max);
    112     delTrie(root);
    113     }
    114     return 0;
    115 }
    View Code

    1323的这份写的更清晰一点

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #define REP(i,a,b) for(int i = a; i < b; i++)
     4 int n,m,flag,a[100005];
     5 int str[32];
     6 struct Trie
     7 {
     8     Trie *next[2];
     9     int v;
    10 };
    11 Trie *root;
    12 int init(int n)
    13 {
    14     int k = 1;
    15     REP(i,0,31) {
    16         if((k<<i)&n) str[30-i]=1;
    17         else str[30-i]=0;
    18     }
    19     return 0;
    20 }
    21 void create(int n)
    22 {
    23     init(n);
    24     Trie *p = root, *q;
    25     REP(i,0,31) {
    26         int id = str[i];
    27         if(p->next[id]==NULL)
    28         {
    29             q=(Trie*)malloc(sizeof(Trie));
    30             REP(j,0,2) {
    31                 q->next[j]=NULL;
    32             }
    33             q->v=0;
    34             p->next[id]=q;
    35         }
    36         p=p->next[id];
    37     }
    38     p->v=n;
    39 }
    40 int find(int n)
    41 {
    42     init(n);
    43     Trie *p = root;
    44     REP(i,0,31) {
    45         int id = str[i];
    46         if(p->next[(id+1)%2]!=NULL) p=p->next[(id+1)%2];
    47         else p=p->next[id];
    48     }
    49     return (p->v)^n;
    50 }
    51 int del(Trie *p)
    52 {
    53     if(p==NULL) return 0;
    54     REP(i,0,2) {
    55         if(p->next[i]!=NULL) del(p->next[i]);
    56     }
    57     free(p);
    58     return 0;
    59 }
    60 int main()
    61 {
    62     while(scanf("%d%d",&n,&m)!=EOF)
    63     {
    64         flag=0;
    65         root=(Trie*)malloc(sizeof(Trie));
    66         REP(i,0,2) {
    67             root->next[i]=NULL;
    68         }
    69         REP(i,0,n) {
    70             scanf("%d",&a[i]);
    71             create(a[i]);
    72         }
    73         REP(i,0,n) {
    74             if(find(a[i])>m)
    75             {
    76                 flag=1;
    77                 break;
    78             }
    79         }
    80         flag?puts("YES"):puts("NO");
    81         del(root);
    82     }
    83     return 0;
    84 }
    View Code

    COJ 1115 最短的名字

    http://122.207.68.93/OnlineJudge/problem.php?id=1115

    第八届湖南省赛的题目 有很多种解法 我是用字典树做的

    对整个村所有的名字建树 建树过程中根据v来标记已经存在的和不存在的结点

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<vector>
      6 #define MAXN 26
      7 
      8 using namespace std;
      9 
     10 typedef struct Trie
     11 {
     12   Trie *next[MAXN];
     13   int v;
     14 }Trie;
     15 Trie *root;
     16 void createTrie(string s)
     17 {
     18   int n = s.length();
     19   char str[n];
     20   strcpy(str, s.c_str());
     21   Trie *p = root, *q;
     22   for (int i = 0; i < strlen(str); ++i)
     23   {
     24     int id = str[i] - 'a';
     25     if (p->next[id] == NULL)
     26     {
     27       q = (Trie*)malloc(sizeof(Trie));
     28       q->v = 1;
     29       for (int j = 0; j < MAXN; ++j)
     30       {
     31         q->next[j] = NULL;
     32       }
     33       p->next[id] = q;
     34       p = p->next[id];
     35     }else
     36     {
     37       p->next[id]->v++;
     38       p = p->next[id];
     39     }
     40   }
     41 }
     42 int findTrie(string s)
     43 {
     44   int n = s.length();
     45   char str[n];
     46   strcpy(str, s.c_str());
     47   Trie *p = root;
     48   for (int i = 0; i < strlen(str); ++i)
     49   {
     50     int id = str[i] - 'a';
     51     if (p->next[id]->v == 1)
     52     {
     53       return i+1;
     54     }else
     55     {
     56       p = p->next[id];
     57     }
     58   }
     59   return strlen(str);
     60 }
     61 void deleteTrie(Trie *T)
     62 {
     63   for (int i = 0; i < MAXN; ++i)
     64   {
     65     if (T->next[i] != NULL)
     66     {
     67       deleteTrie(T->next[i]);
     68     }
     69   }
     70   free(T);
     71 }
     72 int main()
     73 {
     74   int T, n;
     75   scanf("%d", &T);
     76   while(T--)
     77   {
     78     vector<string> strArray;
     79     int ans = 0;
     80     root = (Trie*)malloc(sizeof(Trie));
     81     for (int i = 0; i < MAXN; ++i)
     82     {
     83       root->next[i] = NULL;
     84     }
     85     scanf("%d", &n);
     86     string s;
     87     for (int i = 0; i < n; ++i)
     88     {
     89       cin >> s;
     90       createTrie(s);
     91       strArray.push_back(s);
     92     }
     93     for (int i = 0; i < strArray.size(); i++)
     94     {
     95         ans += findTrie(strArray[i]);
     96     }
     97     printf("%d
    ", ans);
     98     deleteTrie(root);
     99   }
    100   return 0;
    101 }
    View Code

    持续更新中...

  • 相关阅读:
    bzoj4289
    bzoj3033
    bzoj3144
    896C
    bzoj4430
    bzoj4455
    bzoj5117
    BZOJ 1564: [NOI2009]二叉查找树
    BZOJ1261: [SCOI2006]zh_tree
    BZOJ1090: [SCOI2003]字符串折叠
  • 原文地址:https://www.cnblogs.com/grubbyskyer/p/3915159.html
Copyright © 2011-2022 走看看