• poj 2945 trie树统计字符串出现次数


    用记录附加信息的val数组记录次数即可。

    trie的原理:每个可能出现的字目给一个编号c,那么整个树就是一个c叉树

    ch[u][c]表示 节点u走c边过去之后的节点

    PS:trie树还有种动态写法,使用指针和动态分配内存代替了连续的ch数组,更加节省内存。

    Reference:http://blog.csdn.net/architect19/article/details/8966247

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 using namespace std;
     5 #define maxnode 400010
     6 #define sigma_size 22
     7 
     8 char a[maxnode][sigma_size];
     9 int t[maxnode];
    10 int n,m;
    11 //struct Trie
    12 //{
    13     int ch[maxnode][sigma_size];        //ch[i][j]:记录结点i的那个编号为j的子节点
    14     int val[maxnode];                    //val[i]:i节点的附加信息,
    15                                          //若val[i]=0不是还没到单词结束。否则val[i]为该单词的出现次数
    16     int sz;
    17     void Trie()
    18     {
    19         sz=1;
    20         memset(ch,0,sizeof(ch));
    21         memset(val,0,sizeof(val));
    22         memset(t,0,sizeof(t));
    23     }
    24     int idx(char c)                       //idx(c)即字符c的编号。
    25     {
    26         //A G C T
    27         if (c=='A')     return 1;
    28         if (c=='G')     return 2;
    29         if (c=='C')     return 3;
    30         if (c=='T')     return 4;
    31         //return c-'A';                    //第一个字符是A
    32     }
    33     void Insert(char s[sigma_size],int v)
    34     {
    35         int u=0,n=strlen(s);
    36         for (int i=0;i<n;i++)
    37         {
    38             int c=idx(s[i]);
    39             if (!ch[u][c])
    40             {
    41                 memset(ch[sz],0,sizeof(ch[sz]));
    42                 val[sz]=0;
    43                 ch[u][c]=sz++;
    44             }
    45             u=ch[u][c];
    46         }
    47         //val[u]=v;
    48         val[u]+=v;
    49     }
    50     int Query(char s[sigma_size])     //times of s
    51     {
    52         int u=0,c;
    53         int tm=strlen(s);
    54         for (int i=0;i<tm;i++)
    55         {
    56             //c=s[i]-'A';
    57             c=idx(s[i]);
    58             if (!ch[u][c])    return 0;
    59             u=ch[u][c];
    60             //if (val[u]==1)  return true;    //若此时s还没走完但trie树上已经走到结尾了,即树上单词是s的前缀
    61         }
    62         return val[u];
    63     }
    64 //};
    65 
    66 int main()
    67 {
    68     //freopen("in.txt","r",stdin);
    69     //ios::sync_with_stdio(false);
    70 
    71     //while (cin>>n>>m)
    72     while(~scanf("%d%d",&n,&m))
    73     {
    74         Trie();
    75         if ((n!=0)&&(m!=0))
    76         {
    77             for (int i=1;i<=n;i++)
    78             {
    79                 //cin>>a[i];
    80                 scanf("%s",a[i]);
    81                 Insert(a[i],1);
    82             }
    83             for (int i=1;i<=n;i++)
    84             {
    85                 int tm=Query(a[i]);
    86                 t[tm]++;
    87             }
    88             for (int i=1;i<=n;i++)
    89                 printf("%d
    ",t[i]/i);
    90             //cout<<endl;
    91         }
    92         else break;
    93     }
    94 
    95     return 0;
    96 }
  • 相关阅读:
    System 类的使用
    StringBuffer 与 StringBuilder类的使用
    String 类 的 使用
    多线程
    音乐播放
    数据库
    表示图编辑
    UITextView(2)
    UITextView
    tarBar
  • 原文地址:https://www.cnblogs.com/pdev/p/4177366.html
Copyright © 2020-2023  润新知