POJ 2418 Hardwood Species 【Trie树+DFS】

<题目链接>

题目大意:

 给你一堆字符串,让你按字典序输出他们出现的频率.

解题分析:

 首先,这是Trie数词频统计的题目,以Trie树的边储存字母,节点存储以该节点结尾的链所代表的字符串的数量,最后用dfs寻找Trie树中所有的单词,下面代码是用数组实现的Trie树。当然,本题也可用快排或者map直接水过。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 const int MAXN = 10000*35;  
 7 const int SIZE = 130;    //ASCII中有128个常用字符
 8 char str[40];
 9 int all;
10 struct Trie{
11      int ch[MAXN][SIZE];
12      int num[MAXN];
13      int pos;   //sz为遍历到该节点的编号
14      void init(){
15         pos = 1;   
16         memset(ch[0],0,sizeof(ch[0]));
17      }
18      int idx(char c){return c - ' ';}    //因为本题的字符范围是所有字符,所以这里是减去字符中ASCII最小的 ' '(空格)
19      void insert(char *s){
20         int now = 0,n = strlen(s);
21         for(int i=0;i<n;i++){
22             int next = idx(s[i]);
23             if(!ch[now][next]){   //如果该节点没遍历过,那么就新建该节点
24                 memset(ch[pos],0,sizeof(ch[pos]));  //注意这里是ch[pos],而不是ch[now],因为now之前可能已经由其它的子节点了
25                 ch[now][next] = pos++;   //若该节点没被遍历过,给该节点编号
26                 num[now] = 0; 
27             }
28             now = ch[now][next];
29         }
30         num[now]++;
31      }
32      void dfs(int u,int t){
33          str[t] = '\0';   //str[]存下该单词的每一位字符,虽然一开始就给每一位都赋'\0',但是如果该位置的字符符合要求,'\0'就会被该字符覆盖,不影响结果
34          if(num[u])printf("%s %.4f\n",str,(double)num[u]*100/all);    //如果遍历到前缀是完整单词的节点,则将该单词输出
35          for(int i = 0;i < SIZE;i ++){
36              if(ch[u][i]){
37                  str[t] = i+' ';    //第t位存下该字符
38                  dfs(ch[u][i],t+1);
39              }
40          }
41      }
42 }word;
43 int main(){
44     word.init();
45     char s[40];
46     all = 0;
47     while(gets(s)){
48         if(s[0]=='\0')break;
49         word.insert(s);
50         all++ ;    //记录所有单词个数
51     }
52     word.dfs(0,0);
53     return 0;
54 }

 

 快排+map

#include <cstdio>
#include <vector>
#include <map>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;

const int N = 1e4+5;
const int M = 1e6+5;
map<string,int>mp;
vector<string>vec;

int main(){
    string str;
    int cnt=0;
    while(getline(cin,str)){
        if(!mp[str])vec.push_back(str);
        mp[str]++;
        cnt++;
    }
    sort(vec.begin(),vec.end());
    for(int i=0;i<vec.size();i++){
        cout<<vec[i]<<" ";
        printf("%.4lf\n",(mp[vec[i]]/cnt*1.0)*1.0*100);
    }
}

 

 

2018-10-27

转载于:https://www.cnblogs.com/00isok/p/9859366.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值