1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
23 #include <algorithm>
24 #include <cctype>
25 #include <fstream>
26 #include <iomanip>
27 #include <iostream>
28 #include <map>
29 #include <string>
30 #include <vector>
31
32 using std::endl;
33 using std::cout;
34
35 int main (int argc, char const *argv[]) {
36 typedef std::map<char, int> CharMap;
37 typedef CharMap::iterator CharMapIter;
38
39 bool skip_punct = true;
40 bool skip_ws = true;
41 bool conflate_case = true;
42
43 44 int total_chars = 0;
45 CharMap cc;
46 std::string s;
47 while(getline(std::cin, s)) {
48 for(size_t i = 0; i < s.length(); ++i) {
49 char c = s[i];
50 if (conflate_case) {
51 c = std::toupper(c);
52 }
53 if ((skip_punct && std::ispunct(c))
54 || (skip_ws && std::isspace(c))) {
55 continue;
56 }
57 cc[c]++;
58 total_chars++;
59 }
60 }
61
62 63 typedef std::multimap<int, char> MultMap;
64 typedef MultMap::const_iterator MultMapIter;
65 MultMap mm;
66 std::vector<int> counts(cc.size());
67 for(CharMapIter it = cc.begin(); it != cc.end(); it++) {
68 mm.insert(std::pair<int,char>(it->second, it->first));
69 counts.push_back(it->second);
70 }
71
72 std::sort(counts.begin(), counts.end());
73 74 75 typedef std::vector<int>::reverse_iterator RevIter;
76 int previous = -1;
77 for(RevIter it = counts.rbegin(); it != counts.rend(); ++it) {
78 if(*it == previous) {
79 continue;
80 }
81 previous = *it;
82 for(MultMapIter iter = mm.lower_bound(*it);
83 iter != mm.upper_bound(*it); ++iter) {
84 float percent = float(iter->first)/float(total_chars) * 100;
85 cout << " char: " << iter->second << " " << std::setw(4)
86 << iter->first << " [" << std::fixed << std::setprecision(2)
87 << percent << "%]" << endl;
88 }
89 }
90 return 0;
91 }