zoukankan      html  css  js  c++  java
  • UVA 11732——Trie

    解题思路:

      首先我们可以发现:

        1.若两个字符串A、B不相等,且它们的公共前缀为S,则它们的比较次数为:2 * len(S) + 1;

        2.若两个字符串相等,设为A,则它们的比较次数为 2 * ( len(A) + 1 )    //注意考虑结束符''

      那么我们可以建立前缀树,在向前缀树中插入字符串的过程中,如果遇到分叉结点则需要进行比较。

      特别注意:"aaaa","aa"以及"aaaa","aaaa"的情况

      具体做法:

        Trie维护每个结点的val和flag,其中val表示经过每个结点的字符串个数,flag表示是否是分叉结点。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cctype>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 const int maxnode = 4000*1000 + 10;
     9 const int _size = 63;
    10 long long ans;
    11 
    12 struct Trie {
    13     int ch[maxnode][_size];
    14     int val[maxnode];
    15     int flag[maxnode];
    16     int sz;
    17     Trie() {
    18         sz = 1;
    19         memset(ch[0], 0, sizeof (ch[0]));
    20     }
    21     int idx(int c) {
    22         if(c == '') return 62;
    23         else if(isdigit(c)) return c - '0';
    24         else if(c >= 'A' && c <= 'Z') return c - 'A' + 10;
    25         else return c - 'a' + 36;
    26     }
    27     
    28     void insert(char *s) {
    29         int u = 0, n = strlen(s);
    30         val[u]++;
    31         int i;
    32         for(i = 0; i <= n; i++) {
    33             int c = idx(s[i]);
    34             if(!ch[u][c]) {
    35                 memset(ch[sz], 0, sizeof (ch[sz]));
    36                 ch[u][c] = sz++;
    37                 val[ch[u][c]] = 1;
    38                 if(val[u] > 1){
    39                     flag[u] = 1;
    40                     ans += (2*i+1) * (val[u]-val[ch[u][c]]);
    41                 }
    42             }
    43             else {
    44                 val[ch[u][c]]++;
    45                 if(flag[u]) ans += (2*i+1) * (val[u]-val[ch[u][c]]);
    46             }
    47             u = ch[u][c];
    48             
    49         }
    50         if(val[u] > 1) {
    51             flag[u] = 1;
    52             ans += (2*i) * (val[u]-1);
    53         }
    54     }
    55     
    56     void clear() {
    57         sz = 1;
    58         memset(val, 0 , sizeof val);
    59         memset(ch[0], 0, sizeof (ch[0]));
    60         memset(flag, 0, sizeof flag);
    61     }
    62 };
    63 
    64 char s[1010];
    65 Trie T;
    66 
    67 int main(int argc, const char * argv[]) {
    68    
    69     int n;
    70     int kase = 1;
    71     while(scanf("%d", &n) == 1 && n) {
    72         T.clear();
    73         ans = 0;
    74         for(int i = 0; i < n; i++) {
    75             scanf("%s", s);
    76             T.insert(s);
    77         }
    78         
    79         printf("Case %d: %lld
    ", kase++, ans);
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    数据库常用面试题
    Base64、Md5、Des加密
    C#反射类型的使用
    C# 反射工厂模式的实现
    生成验证码的例子
    轻松实现页面提交时,显示“提交中..” (转)
    编写高性能 Web 应用程序的 10 个技巧 (转)
    由Duwamish学习web.config的配置(转)
    .Net配置文件常用配置说明 (转)
    用asp.net还原与恢复sqlserver数据库(转)
  • 原文地址:https://www.cnblogs.com/Kiraa/p/6046408.html
Copyright © 2011-2022 走看看