Seredenko-V

Untitled

Aug 4th, 2022 (edited)
302
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.94 KB | None | 0 0
  1. #pragma once
  2. #include "string_processing.h"
  3. #include "document.h"
  4. #include "log_duration.h"
  5.  
  6. #include <stdexcept>
  7. #include <string>
  8. #include <string_view>
  9. #include <vector>
  10. #include <set>
  11. #include <map>
  12. #include <tuple>
  13. #include <numeric>
  14. #include <algorithm>
  15. #include <cmath>
  16. #include <execution>
  17. #include <utility>
  18. #include <functional>
  19.  
  20. const int MAX_RESULT_DOCUMENT_COUNT = 5;
  21. const double DELTA = 1e-6;
  22.  
  23. class SearchServer {
  24. public:
  25.     template <typename StringContainer>
  26.     SearchServer(const StringContainer& stop_words);
  27.     // Invoke delegating constructor from string container
  28.     explicit SearchServer(const std::string& stop_words_text);
  29.     explicit SearchServer(const std::string_view stop_words_text);
  30.  
  31.     //void AddDocument(int document_id, const std::string& document, DocumentStatus status,
  32.     //    const std::vector<int>& ratings);
  33.     void AddDocument(int document_id, const std::string_view document, DocumentStatus status,
  34.         const std::vector<int>& ratings);
  35.  
  36.     template <typename DocumentPredicate>
  37.     std::vector<Document> FindTopDocuments(const std::string_view raw_query, DocumentPredicate document_predicate) const;
  38.     std::vector<Document> FindTopDocuments(const std::string_view raw_query, DocumentStatus status) const;
  39.     std::vector<Document> FindTopDocuments(const std::string_view raw_query) const;
  40.     //std::vector<Document> FindTopDocuments(const std::string& raw_query, DocumentPredicate document_predicate) const;
  41.     //std::vector<Document> FindTopDocuments(const std::string& raw_query, DocumentStatus status) const;
  42.     //std::vector<Document> FindTopDocuments(const std::string& raw_query) const;
  43.  
  44.     // Поиск интересующих слов в конкретном документе
  45.     std::tuple<std::vector<std::string_view>, DocumentStatus> MatchDocument(const std::string_view raw_query,
  46.         int document_id) const;
  47.     std::tuple<std::vector<std::string_view>, DocumentStatus> MatchDocument(std::execution::sequenced_policy,
  48.         const std::string_view raw_query, int document_id) const;
  49.     std::tuple<std::vector<std::string_view>, DocumentStatus> MatchDocument(std::execution::parallel_policy,
  50.         const std::string_view raw_query, int document_id) const;
  51.     //std::tuple<std::vector<std::string>, DocumentStatus> MatchDocument(const std::string& raw_query,
  52.     //    int document_id) const;
  53.     //std::tuple<std::vector<std::string>, DocumentStatus> MatchDocument(std::execution::sequenced_policy,
  54.     //    const std::string& raw_query, int document_id) const;
  55.     //std::tuple<std::vector<std::string>, DocumentStatus> MatchDocument(std::execution::parallel_policy,
  56.     //    const std::string& raw_query, int document_id) const;
  57.  
  58.     int GetDocumentCount() const;
  59.     const std::map<std::string_view, double>& GetWordFrequencies(int document_id) const;
  60.     //const std::map<std::string, double>& GetWordFrequencies(int document_id) const;
  61.     void RemoveDocument(int document_id);
  62.     void RemoveDocument(std::execution::sequenced_policy, int document_id);
  63.     void RemoveDocument(std::execution::parallel_policy, int document_id);
  64.  
  65.     std::set<int>::const_iterator begin();
  66.     std::set<int>::const_iterator end();
  67.  
  68. private:
  69.     std::set<int> order_addition_document_;
  70.     struct DocumentData {
  71.         int rating;
  72.         DocumentStatus status;
  73.     };
  74.     const std::set<std::string, std::less<>> stop_words_;
  75.     // частота слова в каждом документе
  76.     std::map<std::string_view, std::map<int, double>> word_to_document_freqs_;
  77.     std::map<int, DocumentData> documents_;
  78.     // частоты каждого слова в документе
  79.     std::map<int, std::map<std::string, double, std::less<>>> word_frequencies_in_document_;
  80.     //std::map<int, std::map<std::string, double>> word_frequencies_in_document_;
  81.     //std::map<std::string, double> empty_;
  82.  
  83.  
  84.  
  85.     bool IsStopWord(const std::string_view word) const;
  86.     std::vector<std::string_view> SplitIntoWordsNoStop(const std::string_view text) const;
  87.     //std::vector<std::string> SplitIntoWordsNoStop(const std::string& text) const;
  88.     static int ComputeAverageRating(const std::vector<int>& ratings);
  89.  
  90.     struct QueryWord {
  91.         std::string_view data;
  92.         bool is_minus;
  93.         bool is_stop;
  94.     };
  95.  
  96.     QueryWord ParseQueryWord(std::string_view text) const;
  97.  
  98.     //struct Query {
  99.     //    std::vector<std::string> plus_words;
  100.     //    std::vector<std::string> minus_words;
  101.     //};
  102.  
  103.     struct Query {
  104.         std::vector<std::string_view> plus_words;
  105.         std::vector<std::string_view> minus_words;
  106.     };
  107.  
  108.     //Query ParseQuery(const std::string& text, bool sequenced_policy = true) const;
  109.     Query ParseQuery(const std::string_view text, bool sequenced_policy = true) const;
  110.     // Existence required
  111.     double ComputeWordInverseDocumentFreq(const std::string_view word) const;
  112.  
  113.     template <typename DocumentPredicate>
  114.     std::vector<Document> FindAllDocuments(const Query& query, DocumentPredicate document_predicate) const;
  115.  
  116.     //static bool IsValidWord(const std::string& word);
  117.     static bool IsValidWord(const std::string_view word);
  118. };
  119.  
  120. template <typename StringContainer>
  121. SearchServer::SearchServer(const StringContainer& stop_words)
  122.     : stop_words_(MakeUniqueNonEmptyStrings(stop_words)) {
  123.     for (const auto& word : stop_words) {
  124.         if (!IsValidWord(word)) {
  125.             throw std::invalid_argument("Стоп-слово \""s + std::string(word) + "\" содержит недопустимые символы."s);
  126.         }
  127.     }
  128. }
  129.  
  130. template <typename DocumentPredicate>
  131. std::vector<Document> SearchServer::FindTopDocuments(const std::string_view raw_query, DocumentPredicate document_predicate) const {
  132.     //LOG_DURATION_STREAM("FindTopDocuments"s, std::cout);
  133.     const Query query = ParseQuery(raw_query);
  134.     if (!IsValidWord(raw_query)) {
  135.         throw std::invalid_argument("Содержимое запроса содержит недопустимые символы"s);
  136.     }
  137.     std::vector<Document> matched_documents = FindAllDocuments(query, document_predicate);
  138.     sort(matched_documents.begin(), matched_documents.end(), [](const Document& lhs, const Document& rhs) {
  139.         if (std::abs(lhs.relevance - rhs.relevance) < DELTA) {
  140.             return lhs.rating > rhs.rating;
  141.         } else {
  142.             return lhs.relevance > rhs.relevance;
  143.         }
  144.         });
  145.     if (matched_documents.size() > MAX_RESULT_DOCUMENT_COUNT) {
  146.         matched_documents.resize(MAX_RESULT_DOCUMENT_COUNT);
  147.     }
  148.     return matched_documents;
  149. }
  150.  
  151. template <typename DocumentPredicate>
  152. std::vector<Document> SearchServer::FindAllDocuments(const SearchServer::Query& query, DocumentPredicate document_predicate) const {
  153.     std::map<int, double> document_to_relevance;
  154.     for (const std::string_view word : query.plus_words) {
  155.         if (word_to_document_freqs_.count(word) == 0) {
  156.             continue;
  157.         }
  158.         const double inverse_document_freq = ComputeWordInverseDocumentFreq(word);
  159.         for (const auto& [document_id, term_freq] : word_to_document_freqs_.at(word)) {
  160.             const auto& document_data = documents_.at(document_id);
  161.             if (document_predicate(document_id, document_data.status, document_data.rating)) {
  162.                 document_to_relevance[document_id] += term_freq * inverse_document_freq;
  163.             }
  164.         }
  165.     }
  166.  
  167.     for (const std::string_view word : query.minus_words) {
  168.         if (word_to_document_freqs_.count(word) == 0) {
  169.             continue;
  170.         }
  171.         for (const auto [document_id, _] : word_to_document_freqs_.at(word)) {
  172.             document_to_relevance.erase(document_id);
  173.         }
  174.     }
  175.  
  176.     std::vector<Document> matched_documents;
  177.     for (const auto [document_id, relevance] : document_to_relevance) {
  178.         matched_documents.push_back({ document_id, relevance, documents_.at(document_id).rating });
  179.     }
  180.     return matched_documents;
  181. }
Advertisement
Add Comment
Please, Sign In to add comment