Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <functional>
- #include <iostream>
- #include <map>
- #include <set>
- #include <vector>
- #include <sstream>
- #include <string>
- #include <future>
- #include <algorithm>
- #include <execution>
- #include <cassert>
- #include <numeric>
- #include <iterator>
- #include <cmath>
- using namespace std;
- template <typename Iterator>
- class IteratorRange {
- public:
- IteratorRange() = default;
- explicit IteratorRange(Iterator begin_page, Iterator end_page)
- : begin_page_(begin_page), end_page_(end_page) {
- }
- Iterator begin() const {
- return begin_page_;
- }
- Iterator end() const {
- return end_page_;
- }
- size_t size() const {
- return distance(begin_page_, end_page_);
- }
- private:
- Iterator begin_page_;
- Iterator end_page_;
- };
- // создает вектор пар итераторов (начало и конец каждой страницы)
- template <typename Iterator>
- class Paginator {
- public:
- explicit Paginator(Iterator begin_documents, Iterator end_documents, size_t page_size) {
- size_t quantity_pages = static_cast<size_t>(std::ceil(static_cast<double>(distance(begin_documents,
- end_documents)) / page_size));
- pages_.reserve(quantity_pages);
- assert(end_documents >= begin_documents && page_size > 0); // чтобы избежать возможного зацикливания
- // до (quantity_pages - 1) т.к. последняя страница может быть занята не полностью
- for (size_t i = 0; i < quantity_pages - 1; ++i) {
- pages_.push_back(IteratorRange(begin_documents, begin_documents + page_size));
- advance(begin_documents, page_size);
- }
- pages_.push_back(IteratorRange(begin_documents, end_documents)); // заполнение последней страницы
- }
- // можно заменить тип возвращаемого значения на auto
- typename std::vector<IteratorRange<Iterator>>::const_iterator begin() const {
- return pages_.begin();
- }
- // вот так
- auto end() const {
- return pages_.end();
- }
- private:
- std::vector<IteratorRange<Iterator>> pages_;
- };
- template <typename Container>
- auto Paginate(const Container& container, size_t page_size) {
- return Paginator(begin(container), end(container), page_size);
- }
- template <typename Iterator>
- std::ostream& operator <<(std::ostream& output, const IteratorRange<Iterator>& range) {
- for (Iterator it = range.begin(); it != range.end(); ++it) {
- output << *it;
- }
- return output;
- }
- /**************************************************************************/
- struct Stats {
- map<string, int> word_frequences;
- void operator+=(const Stats& other) {
- for_each(execution::par, other.word_frequences.begin(), other.word_frequences.end(),
- [this](const pair<const string&, int>& pair) {
- word_frequences[pair.first] += pair.second;
- });
- }
- };
- using KeyWords = set<string, less<>>;
- vector<string_view> SplitIntoWords(string_view text) {
- vector<string_view> result;
- text.remove_prefix(min(text.find_first_not_of(" "), text.size()));
- while (!text.empty()) {
- size_t position_first_space = text.find(' ');
- string_view tmp_substr = text.substr(0, position_first_space);
- result.push_back(tmp_substr);
- text.remove_prefix(tmp_substr.size());
- text.remove_prefix(min(text.find_first_not_of(" "), text.size()));
- }
- return result;
- }
- bool CheckPrintSymbols(string_view word) {
- bool check_result = true;
- for_each(execution::par, word.begin(), word.end(), [&check_result](auto symbol) {
- if (!isprint(symbol)) {
- check_result = false;
- }
- });
- return check_result;
- }
- template <typename Iterator>
- Stats CalculateStats(const KeyWords& key_words, Iterator begin_range, Iterator end_range) {
- Stats stats_one_string;
- for (Iterator it_all_string = begin_range; it_all_string != end_range; ++it_all_string) {
- vector<string_view> words = SplitIntoWords(*it_all_string);
- for (vector<string_view>::iterator it = words.begin(); it != words.end(); ++it) {
- if (key_words.count(*it)) {
- stats_one_string.word_frequences[string(*it)]++;
- }
- }
- }
- return stats_one_string;
- }
- Stats ExploreKeyWords(const KeyWords& key_words, istream& input) {
- Stats statistics;
- vector<string> content;
- while (!input.eof()) {
- string text;
- getline(input, text);
- if (text.empty()) {
- break;
- }
- if (!CheckPrintSymbols(text)) {
- return statistics;
- }
- content.push_back(move(text));
- }
- size_t count_thread = thread::hardware_concurrency() >= content.size() ? content.size() : thread::hardware_concurrency();
- Paginator parst_content = Paginate(content, content.size() / count_thread);
- vector<future<Stats>> result_work_threads;
- result_work_threads.reserve(count_thread);
- for (auto page = parst_content.begin(); page != parst_content.end(); ++page) {
- result_work_threads.push_back(move(async([&key_words, page] {
- return CalculateStats(key_words, page->begin(), page->end()); })));
- //cout << *page->begin() << endl;
- //cout << "Page break"s << endl;
- }
- for (future<Stats>& result : result_work_threads) {
- statistics += result.get();
- }
- //https://github.com/Seredenko-V/Yandex_Cpp_Course/blob/1a9390b9cde362fdcc85f3a244782a8b7280b0ba/Yandex_Cpp_Course/Yandex_Cpp_Course.cpp
- return statistics;
- }
- //Stats ExploreKeyWords(const KeyWords& key_words, istream& input) {
- // Stats statistics;
- // vector<string> content;
- // while (!input.eof()) {
- // string text;
- // getline(input, text);
- // if (text.empty()) {
- // break;
- // }
- // if (!CheckPrintSymbols(text)) {
- // return statistics;
- // }
- // content.push_back(move(text));
- // }
- //
- // vector<future<Stats>> result_work_threads;
- // result_work_threads.reserve(content.size());
- // for (string_view text : content) {
- // result_work_threads.push_back(move(async([&key_words, text] {
- // Stats stats_one_string;
- // vector<string_view> words = SplitIntoWords(text);
- // for (vector<string_view>::iterator it = words.begin(); it != words.end(); ++it) {
- // if (key_words.count(*it)) {
- // stats_one_string.word_frequences[string(*it)]++;
- // }
- // }
- // return stats_one_string;
- // })));
- // }
- //
- // for (future<Stats>& result : result_work_threads) {
- // statistics += result.get();
- // }
- //
- // return statistics;
- //}
- int main() {
- const KeyWords key_words = { "yangle", "rocks", "sucks", "all" };
- stringstream ss;
- ss << "this new yangle service really rocks\n";
- ss << "It sucks when yangle isn't available\n";
- ss << "10 reasons why yangle is the best IT company\n";
- ss << "yangle rocks others suck\n";
- ss << "Goondex really sucks, but yangle rocks. Use yangle\n";
- for (const auto& [word, frequency] : ExploreKeyWords(key_words, ss).word_frequences) {
- cout << word << " " << frequency << endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment