-
Notifications
You must be signed in to change notification settings - Fork 0
/
array_hash.cpp
94 lines (74 loc) · 2.4 KB
/
array_hash.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "common.hpp"
#include "helpers.hpp"
#include "timer.hpp"
#include <tsl/array_map.h>
#include <fmt/color.h>
#include <fmt/format.h>
#include <algorithm>
#include <fstream>
#include <functional>
#include <iterator>
#include <string>
#include <string_view>
#include <tuple>
#include <type_traits>
#include <vector>
#include <cctype>
#include <cstdint>
#include <cstdlib>
int main(int argc, char * argv[])
{
Timer timer{fmt::format(fg(fmt::color::dark_green), "total")};
if (argc < 3) {
return EXIT_FAILURE;
}
std::ifstream i(argv[1]);
if (!i.is_open()) {
return EXIT_FAILURE;
}
i.seekg(0, std::ios::end);
auto size = i.tellg();
i.seekg(0, std::ios::beg);
std::string input;
input.resize(std::size_t(size));
i.read(input.data(), std::streamsize(size));
timer.report("read input");
auto toLowerChar = [](char c) {
return char(std::tolower(std::make_unsigned_t<char>(c)));
};
std::transform(std::cbegin(input), std::cend(input), std::begin(input),
toLowerChar);
timer.report("make input lowercase");
tsl::array_map<char, uint32_t> wordCounts;
auto isAlpha = [](char c) {
return bool(std::isalpha(std::make_unsigned_t<char>(c)));
};
auto end = std::next(input.data(), input.size());
auto beg = std::find_if(input.data(), end, isAlpha);
while (beg != end) {
auto it = std::find_if_not(beg, end, isAlpha);
++wordCounts[std::string_view{beg, std::size_t(std::distance(beg, it))}];
beg = std::find_if(it, end, isAlpha);
}
timer.report(fmt::format(fg(fmt::color::dark_blue), "count words"));
std::vector<std::pair<std::string_view, uint32_t>> output;
output.reserve(wordCounts.size());
for(auto it = wordCounts.cbegin(); it != wordCounts.cend(); ++it) {
output.emplace_back(it.key(), it.value());
}
auto isLess = [](auto lhs, auto rhs) -> bool {
return std::tie(rhs.second, lhs.first) <
std::tie(lhs.second, rhs.first);
};
std::sort(std::begin(output), std::end(output), isLess);
timer.report(fmt::format(fg(fmt::color::dark_orange), "sort words"));
std::ofstream o(argv[2]);
if (!o.is_open()) {
return EXIT_FAILURE;
}
for (auto wordCount : output) {
o << wordCount.second << ' ' << wordCount.first << '\n';
}
timer.report("write output");
return EXIT_SUCCESS;
}