zoukankan      html  css  js  c++  java
  • POJ2001Shortest Prefixes(字典树)

    题目大意就是帮你给N条字符串,每条长度不超过20。问要将他们单一识别出来,每个字符串最短可以缩为多短。

    如:

    abc

    abcdefg

    bc

    adef

    这四个字符串就可分别缩写为

    abc

    abcd

    b

    ad

    方法:   字典树(可以参阅http://s.acmore.net/show_article/show/58)。

    另外我还用了一个bool数组last用来记录每个单一识别的字符串最短可以到哪个位置,他的下标就是字典树中每个字母对应的序号

    方法如下:(以上面的为例)

    当输入的字符串在某一个位置开始与之前的不同,就记录这个不同的字母(设置为true),之后的不再改变

    当输入字符串的某位置在建好的树中时,把last加长(设置为true)

    第一次输入:abc          last[0]=true;

    第二次输入:abcdefg    last[0]=last[1]=last[2]=last[3]=true;

    第三次输入:bc            last[0]=true;

    第四次输入:adef         last[0]=last[1]=true;

    这样一来输出端长度就分别为1、4、1、2

    代码实现如下:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 #include <stack>
     6 #include <set>
     7 #include <queue>
     8 #define MAX(a,b) (a) > (b)? (a):(b)
     9 #define MIN(a,b) (a) < (b)? (a):(b)
    10 #define mem(a) memset(a,0,sizeof(a))
    11 #define INF 1000000007
    12 #define MAXN 20005
    13 using namespace std;
    14 
    15 int trie[MAXN][26],val[MAXN],S;
    16 bool last[MAXN];
    17 char ma[1005][30];
    18 
    19 int get_num(char ch){return ch-'a';}
    20 
    21 void init()
    22 {
    23     mem(trie);mem(val);
    24     mem(last);mem(ma);
    25     S = 1;
    26 }
    27 
    28 void insert(char *s)
    29 {
    30     int u=0,len = strlen(s);
    31     int flag = 1;
    32     for(int i=0;i<len;i++)
    33     {
    34         int c = get_num(s[i]);
    35         if(!trie[u][c])
    36         {
    37             trie[u][c] = S;
    38             val[u] = 1;
    39             if(flag)//如果与上面的字符串开始不一样,酒吧第一个开始不一样的位置设置为true
    40             {
    41                 last[u]=true;
    42                 flag = 0;//之后的依然是false
    43             }
    44             u = S;
    45             S++;
    46         }
    47         else if(val[u] == 1)
    48         {
    49             u = trie[u][c];
    50             last[u] = true;//在查找中发现与已建好的树里面相同的数,那么需要识别的字符串就要相应的加长
    51         }
    52     }
    53     if(val[u]==1 || val[u] == 2)return;
    54     else val[u] = 2;
    55 }
    56 
    57 int main()
    58 {
    59     init();
    60     int T =0;
    61     while(scanf("%s",ma[T])!=EOF)
    62     {
    63         insert(ma[T++]);
    64     }
    65     for(int i=0;i<T;i++)
    66     {
    67         printf("%s ",ma[i]);
    68         int u=0,j=0;
    69         while(last[u] && ma[i][j])
    70         {
    71             printf("%c",ma[i][j]);
    72             u = trie[u][get_num(ma[i][j++])];
    73         }
    74         printf("
    ");
    75     }
    76     return 0;
    77 }
  • 相关阅读:
    [每日一题] OCP1z0-047 :2013-07-29 视图――别名
    Java动态规划实现最短路径问题
    Java动态规划实现最短路径问题
    Java实现堆排序问题(变治法)
    Java实现堆排序问题(变治法)
    Java实现堆排序问题(变治法)
    Java实现堆排序问题(变治法)
    Java实现堆排序问题(变治法)
    Java实现8枚硬币问题(减治法)
    Java实现8枚硬币问题(减治法)
  • 原文地址:https://www.cnblogs.com/gj-Acit/p/3175427.html
Copyright © 2011-2022 走看看