Seredenko-V

ExploreKeyWords_v4

Aug 8th, 2022
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.42 KB | None | 0 0
  1. #include <functional>
  2. #include <iostream>
  3. #include <map>
  4. #include <set>
  5. #include <vector>
  6. #include <sstream>
  7. #include <string>
  8.  
  9. #include <future>
  10. #include <algorithm>
  11. #include <execution>
  12. #include <cassert>
  13. #include <numeric>
  14. #include <iterator>
  15. #include <cmath>
  16.  
  17. using namespace std;
  18.  
  19. template <typename Iterator>
  20. class IteratorRange {
  21. public:
  22.     IteratorRange() = default;
  23.     explicit IteratorRange(Iterator begin_page, Iterator end_page)
  24.         : begin_page_(begin_page), end_page_(end_page) {
  25.     }
  26.     Iterator begin() const {
  27.         return begin_page_;
  28.     }
  29.     Iterator end() const {
  30.         return end_page_;
  31.     }
  32.     size_t size() const {
  33.         return distance(begin_page_, end_page_);
  34.     }
  35. private:
  36.     Iterator begin_page_;
  37.     Iterator end_page_;
  38. };
  39.  
  40. // создает вектор пар итераторов (начало и конец каждой страницы)
  41. template <typename Iterator>
  42. class Paginator {
  43. public:
  44.     explicit Paginator(Iterator begin_documents, Iterator end_documents, size_t page_size) {
  45.         size_t quantity_pages = static_cast<size_t>(std::ceil(static_cast<double>(distance(begin_documents,
  46.             end_documents)) / page_size));
  47.         pages_.reserve(quantity_pages);
  48.         assert(end_documents >= begin_documents && page_size > 0); // чтобы избежать возможного зацикливания
  49.         // до (quantity_pages - 1) т.к. последняя страница может быть занята не полностью
  50.         for (size_t i = 0; i < quantity_pages - 1; ++i) {
  51.             pages_.push_back(IteratorRange(begin_documents, begin_documents + page_size));
  52.             advance(begin_documents, page_size);
  53.         }
  54.         pages_.push_back(IteratorRange(begin_documents, end_documents)); // заполнение последней страницы
  55.     }
  56.     // можно заменить тип возвращаемого значения на auto
  57.     typename std::vector<IteratorRange<Iterator>>::const_iterator begin() const {
  58.         return pages_.begin();
  59.     }
  60.     // вот так
  61.     auto end() const {
  62.         return pages_.end();
  63.     }
  64. private:
  65.     std::vector<IteratorRange<Iterator>> pages_;
  66. };
  67.  
  68. template <typename Container>
  69. auto Paginate(const Container& container, size_t page_size) {
  70.     return Paginator(begin(container), end(container), page_size);
  71. }
  72.  
  73. template <typename Iterator>
  74. std::ostream& operator <<(std::ostream& output, const IteratorRange<Iterator>& range) {
  75.     for (Iterator it = range.begin(); it != range.end(); ++it) {
  76.         output << *it;
  77.     }
  78.     return output;
  79. }
  80.  
  81. /**************************************************************************/
  82.  
  83. struct Stats {
  84.     map<string, int> word_frequences;
  85.  
  86.     void operator+=(const Stats& other) {
  87.         for_each(execution::par, other.word_frequences.begin(), other.word_frequences.end(),
  88.             [this](const pair<const string&, int>& pair) {
  89.                 word_frequences[pair.first] += pair.second;
  90.             });
  91.     }
  92. };
  93.  
  94. using KeyWords = set<string, less<>>;
  95.  
  96. vector<string_view> SplitIntoWords(string_view text) {
  97.     vector<string_view> result;
  98.     text.remove_prefix(min(text.find_first_not_of(" "), text.size()));
  99.     while (!text.empty()) {
  100.         size_t position_first_space = text.find(' ');
  101.         string_view tmp_substr = text.substr(0, position_first_space);
  102.         result.push_back(tmp_substr);
  103.         text.remove_prefix(tmp_substr.size());
  104.         text.remove_prefix(min(text.find_first_not_of(" "), text.size()));
  105.     }
  106.     return result;
  107. }
  108.  
  109. bool CheckPrintSymbols(string_view word) {
  110.     bool check_result = true;
  111.     for_each(execution::par, word.begin(), word.end(), [&check_result](auto symbol) {
  112.         if (!isprint(symbol)) {
  113.             check_result = false;
  114.         }
  115.     });
  116.     return check_result;
  117. }
  118.  
  119. template <typename Iterator>
  120. Stats CalculateStats(const KeyWords& key_words, Iterator begin_range, Iterator end_range) {
  121.     Stats stats_one_string;
  122.     for (Iterator it_all_string = begin_range; it_all_string != end_range; ++it_all_string) {
  123.         vector<string_view> words = SplitIntoWords(*it_all_string);
  124.         for (vector<string_view>::iterator it = words.begin(); it != words.end(); ++it) {
  125.             if (key_words.count(*it)) {
  126.                 stats_one_string.word_frequences[string(*it)]++;
  127.             }
  128.         }
  129.     }
  130.     return stats_one_string;
  131. }
  132.  
  133. Stats ExploreKeyWords(const KeyWords& key_words, istream& input) {
  134.     Stats statistics;
  135.     vector<string> content;
  136.     while (!input.eof()) {
  137.         string text;
  138.         getline(input, text);
  139.         if (text.empty()) {
  140.             break;
  141.         }
  142.         if (!CheckPrintSymbols(text)) {
  143.             return statistics;
  144.         }
  145.         content.push_back(move(text));
  146.     }
  147.  
  148.     size_t count_thread = thread::hardware_concurrency() >= content.size() ? content.size() : thread::hardware_concurrency();
  149.     Paginator parst_content = Paginate(content, content.size() / count_thread);
  150.     vector<future<Stats>> result_work_threads;
  151.     result_work_threads.reserve(count_thread);
  152.  
  153.     for (auto page = parst_content.begin(); page != parst_content.end(); ++page) {
  154.         result_work_threads.push_back(move(async([&key_words, page] {
  155.             return CalculateStats(key_words, page->begin(), page->end()); })));
  156.         //cout << *page->begin() << endl;
  157.         //cout << "Page break"s << endl;
  158.     }
  159.  
  160.     for (future<Stats>& result : result_work_threads) {
  161.         statistics += result.get();
  162.     }
  163.  
  164.     //https://github.com/Seredenko-V/Yandex_Cpp_Course/blob/1a9390b9cde362fdcc85f3a244782a8b7280b0ba/Yandex_Cpp_Course/Yandex_Cpp_Course.cpp
  165.  
  166.     return statistics;
  167. }
  168.  
  169. //Stats ExploreKeyWords(const KeyWords& key_words, istream& input) {
  170. //    Stats statistics;
  171. //    vector<string> content;
  172. //    while (!input.eof()) {
  173. //        string text;
  174. //        getline(input, text);
  175. //        if (text.empty()) {
  176. //            break;
  177. //        }
  178. //        if (!CheckPrintSymbols(text)) {
  179. //            return statistics;
  180. //        }
  181. //        content.push_back(move(text));
  182. //    }
  183. //
  184. //    vector<future<Stats>> result_work_threads;
  185. //    result_work_threads.reserve(content.size());
  186. //    for (string_view text : content) {
  187. //        result_work_threads.push_back(move(async([&key_words, text] {
  188. //            Stats stats_one_string;
  189. //            vector<string_view> words = SplitIntoWords(text);
  190. //            for (vector<string_view>::iterator it = words.begin(); it != words.end(); ++it) {
  191. //                if (key_words.count(*it)) {
  192. //                    stats_one_string.word_frequences[string(*it)]++;
  193. //                }
  194. //            }
  195. //            return stats_one_string;
  196. //        })));
  197. //    }
  198. //
  199. //    for (future<Stats>& result : result_work_threads) {
  200. //        statistics += result.get();
  201. //    }
  202. //
  203. //    return statistics;
  204. //}
  205.  
  206. int main() {
  207.     const KeyWords key_words = { "yangle", "rocks", "sucks", "all" };
  208.  
  209.     stringstream ss;
  210.     ss << "this new yangle service really rocks\n";
  211.     ss << "It sucks when yangle isn't available\n";
  212.     ss << "10 reasons why yangle is the best IT company\n";
  213.     ss << "yangle rocks others suck\n";
  214.     ss << "Goondex really sucks, but yangle rocks. Use yangle\n";
  215.  
  216.     for (const auto& [word, frequency] : ExploreKeyWords(key_words, ss).word_frequences) {
  217.         cout << word << " " << frequency << endl;
  218.     }
  219.  
  220.     return 0;
  221. }
Advertisement
Add Comment
Please, Sign In to add comment