poj 2418 简单Trie树

题意:

给出一些字符串,统计出现的次数,并按字典序输出。

分析:

裸的Trie树,因为输出按字符串的字典序输出,所以插入的时候,把第一次出现的字符串暂时保存起来。以后排完序在查询输出即可。

不过这题我发现了一个很神奇的地方,因为我刚开始保存字母节点的时候开的数组是26,如果出现大写字母或空格可定会报错!但是我下面开了一个a数组,仍然开26大小的节点数组,居然没报错!!而且AC了QAQ。并不是数据只有小写字母,也有大写字母和空格,但是下面加个a数组就可以,把a数组删了就报错,好神奇啊!


782ms

#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxnode=300000+10;
const int N=500000+10;

struct Trie
{
    int ch[maxnode][26]; //这个26开小了,因为不只有小写字母,但是在开下面那个a数组居然A了!!可以改大一点
    int val[maxnode];
    int sz,id;
    void clear(){id=1;sz=1;memset(ch[0],0,sizeof(ch[0]));}
    int idx(char c){return c-'a';}

    bool insert(const char *s)
    {
        int u=0,n=strlen(s);
        for(int i=0;i<n;i++){
            int c=idx(s[i]);
            if(!ch[u][c]){
                memset(ch[sz],0,sizeof(ch[sz]));
                val[sz]=0;
                ch[u][c]=sz++;
            }
            u=ch[u][c];
        }
        val[u]++;
        if(val[u]==1)return true;
        return false;
    }
    int query(string s)
    {
        int u=0,n=s.size();
        for(int i=0;i<n;i++){
            int c=idx(s[i]);
            u=ch[u][c];
        }
        return val[u];
    }

};
char s[33];
int a[N];//这个删了就报错,好神奇
Trie trie;
int main()
{
   // freopen("f.txt","r",stdin);
    trie.clear();
    vector<string>ans;
    int tot=0;
    while(gets(s)){
        tot++;
        if(trie.insert(s)){
            ans.push_back(s);
        }
    }
    sort(ans.begin(),ans.end());
    for(int i=0;i<ans.size();i++){
        cout<<ans[i];printf(" %.4f\n",trie.query(ans[i])*100.0/(1.0*tot));
    }
    return 0;
}


posted @ 2016-07-12 20:32  HARD_UNDERSTAND  阅读(186)  评论(0编辑  收藏  举报