chapter 05 exercise solution
parent
2393586493
commit
a756ccb5a4
|
@ -0,0 +1,81 @@
|
|||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
using WordVector = std::vector<std::string>;
|
||||
using WordCountPair = std::pair<std::string, std::size_t>;
|
||||
using CountedWordsMap = std::map<std::string, std::size_t>;
|
||||
|
||||
WordVector split_text(std::string_view text, const std::set<char> &dels);
|
||||
CountedWordsMap count_words(const WordVector &words);
|
||||
|
||||
int main()
|
||||
{
|
||||
auto current_path = fs::current_path();
|
||||
current_path /= "text.txt";
|
||||
|
||||
/* get text */
|
||||
auto text = readFile(current_path.string());
|
||||
std::cout << "---------- text\n";
|
||||
std::cout << text;
|
||||
|
||||
/* make text lowercase */
|
||||
std::transform(text.begin(), text.end(),
|
||||
text.begin(), ::tolower);
|
||||
|
||||
/* split text */
|
||||
std::cout << "\n---------- splitted text\n";
|
||||
auto splitted_text = split_text(text, {' ', '\n', '.'});
|
||||
print_vector(splitted_text);
|
||||
|
||||
/* count word occurences */
|
||||
std::cout << "\n---------- word count\n";
|
||||
auto counted_words = count_words(splitted_text);
|
||||
print_map(counted_words);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CountedWordsMap count_words(const WordVector &words)
|
||||
{
|
||||
auto result = CountedWordsMap{};
|
||||
for (auto word : words) {
|
||||
++result[word];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#define AVG_W_LEN 4
|
||||
WordVector split_text(std::string_view text, const std::set<char> &dels)
|
||||
{
|
||||
size_t start, count;
|
||||
start = count = 0;
|
||||
auto result = WordVector{};
|
||||
/* pre allocate space */
|
||||
result.reserve(text.length() / AVG_W_LEN);
|
||||
|
||||
for (auto c : text) {
|
||||
if (dels.find(c) != dels.end()) {
|
||||
if (count)
|
||||
result.push_back(static_cast<std::string>(text.substr(start, count)));
|
||||
start += count + 1;
|
||||
count = 0;
|
||||
} else
|
||||
++count;
|
||||
}
|
||||
result.shrink_to_fit();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
constexpr double pi = 3.14159265358979311600;
|
||||
|
||||
template <typename T>
|
||||
void print_array(const T *array, const std::size_t length)
|
||||
{
|
||||
for (std::size_t i = 0; i < length - 1; i++)
|
||||
{
|
||||
std::cout << array[i] << ", ";
|
||||
}
|
||||
|
||||
std::cout << array[length - 1] << '\n';
|
||||
}
|
||||
|
||||
template <typename T, std::size_t S>
|
||||
void print_array(const std::array<T, S> array)
|
||||
{
|
||||
for (std::size_t i = 0; i < array.size() - 1; i++)
|
||||
{
|
||||
std::cout << array[i] << ", ";
|
||||
}
|
||||
|
||||
std::cout << array[array.size() - 1] << '\n';
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void print_vector(const std::vector<T> &vector)
|
||||
{
|
||||
for (std::size_t i = 0; i < vector.size() - 1; i++)
|
||||
{
|
||||
std::cout << vector[i] << ", ";
|
||||
}
|
||||
if (vector.size())
|
||||
std::cout << vector[vector.size() - 1] << '\n';
|
||||
}
|
||||
|
||||
template <>
|
||||
void print_vector(
|
||||
const std::vector<std::pair<std::string, std::size_t>> &vector)
|
||||
{
|
||||
for (std::size_t i = 0; i < vector.size() - 1; i++)
|
||||
{
|
||||
std::cout << vector[i].first << ": " << vector[i].second << ", ";
|
||||
}
|
||||
|
||||
std::cout << vector[vector.size() - 1].first << ": "
|
||||
<< vector[vector.size() - 1].second << '\n';
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
void print_map(const std::map<T, U> Map)
|
||||
{
|
||||
for (const auto &[Key, value] : Map)
|
||||
{
|
||||
std::cout << Key << ": " << value << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
std::string readFile(std::string_view file_path)
|
||||
{
|
||||
auto str = std::string{};
|
||||
auto text = std::string{};
|
||||
|
||||
auto iffile = std::ifstream{};
|
||||
iffile.open(file_path.data());
|
||||
|
||||
if (iffile.is_open())
|
||||
{
|
||||
while (std::getline(iffile, str))
|
||||
{
|
||||
text += str + '\n';
|
||||
}
|
||||
}
|
||||
|
||||
iffile.close();
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void random_vector(std::vector<T> &vec)
|
||||
{
|
||||
std::mt19937 random_generator(22);
|
||||
std::uniform_int_distribution<T> random_distribution(-10, 10);
|
||||
|
||||
for (auto &val : vec)
|
||||
{
|
||||
val = random_distribution(random_generator);
|
||||
}
|
||||
}
|
||||
|
||||
void clear_console()
|
||||
{
|
||||
#if defined _WIN32
|
||||
system("cls");
|
||||
#elif defined(__LINUX__) || defined(__gnu_linux__) || defined(__linux__)
|
||||
system("clear");
|
||||
#elif defined(__APPLE__)
|
||||
system("clear");
|
||||
#else
|
||||
system("clear");
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* UTILS_H */
|
Loading…
Reference in New Issue