shizaero

Untitled

Aug 30th, 2023
895
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.87 KB | None | 0 0
  1. #pragma once  
  2.  
  3. #include <algorithm>  
  4. #include <cmath>  
  5. #include <iostream>  
  6. #include <map>  
  7. #include <set>  
  8. #include <stdexcept>  
  9. #include <string>  
  10. #include <utility>  
  11. #include <vector>  
  12. #include <numeric>  
  13. #include <execution>
  14.  
  15. #include "document.h"  
  16. #include "string_processing.h"  
  17. #include "read_input_functions.h"  
  18. #include "paginator.h"  
  19.  
  20. using namespace std::string_literals;  
  21.  
  22. const int MAX_RESULT_DOCUMENT_COUNT = 5;  
  23.  
  24. class SearchServer  
  25. {  
  26. public:  
  27.     struct DocumentData  
  28.     {  
  29.         int rating;  
  30.         DocumentStatus status;  
  31.     };  
  32.  
  33.     std::vector<int>::iterator begin();  
  34.     std::vector<int>::const_iterator begin() const;  
  35.     std::vector<int>::iterator end();  
  36.     std::vector<int>::const_iterator end() const;  
  37.  
  38.     template <typename StringContainer>  
  39.     explicit SearchServer(const StringContainer& stop_words);  
  40.    
  41.     explicit SearchServer(const std::string& stop_words_text);  
  42.    
  43.     void AddDocument(int document_id, const std::string& document, DocumentStatus status, const std::vector<int>& ratings);  
  44.    
  45.     template <typename DocumentPredicate>  
  46.     std::vector<Document> FindTopDocuments(const std::string& raw_query, DocumentPredicate document_predicate) const;  
  47.  
  48.     std::vector<Document> FindTopDocuments(const std::string& raw_query, DocumentStatus status) const;  
  49.  
  50.     std::vector<Document> FindTopDocuments(const std::string& raw_query) const;  
  51.  
  52.     int GetDocumentCount() const;  
  53.  
  54.  
  55.     std::tuple<std::vector<std::string>, DocumentStatus> MatchDocument(const std::string& raw_query, int document_id) const;  
  56.  
  57.  
  58.     void RemoveDocument(int document_id);  
  59.    
  60.     template <typename PAR_SEQ>
  61.     void SearchServer::RemoveDocument(PAR_SEQ parameter, int document_id);
  62.  
  63.     const std::map<std::string, double>& GetWordFrequencies(int document_id) const;  
  64.  
  65.  
  66. private:  
  67.  
  68.     const std::set<std::string> stop_words_;  
  69.     std::map<std::string, std::map<int, double>> word_to_document_freqs_;  
  70.     std::map<int, std::map<std::string, double>> document_to_word_freqs_;  
  71.     std::map<int, DocumentData> documents_;  
  72.     std::vector<int> document_ids_;  
  73.  
  74.     bool IsStopWord(const std::string& word) const;  
  75.  
  76.     static bool IsValidWord(const std::string& word);  
  77.  
  78.     std::vector<std::string> SplitIntoWordsNoStop(const std::string& text) const;  
  79.  
  80.     static int ComputeAverageRating(const std::vector<int>& ratings);  
  81.  
  82.     struct QueryWord  
  83.     {  
  84.         std::string data;  
  85.         bool is_minus;  
  86.         bool is_stop;  
  87.     };  
  88.  
  89.     QueryWord ParseQueryWord(const std::string& text) const;  
  90.  
  91.     struct Query  
  92.     {  
  93.         std::set<std::string> plus_words;  
  94.         std::set<std::string> minus_words;  
  95.     };  
  96.  
  97.     Query ParseQuery(const std::string& text) const;  
  98.  
  99.     double ComputeWordInverseDocumentFreq(const std::string& word) const;  
  100.  
  101.  
  102.     template <typename DocumentPredicate>  
  103.     std::vector<Document> FindAllDocuments(const Query& query,  
  104.         DocumentPredicate document_predicate) const;  
  105. };  
  106.  
  107. template <typename DocumentPredicate>  
  108. std::vector<Document> SearchServer::FindAllDocuments(const Query& query,  
  109.     DocumentPredicate document_predicate) const  
  110. {  
  111.     std::map<int, double> document_to_relevance;  
  112.     for (const std::string& word : query.plus_words)  
  113.     {  
  114.         if (word_to_document_freqs_.count(word) == 0)  
  115.         {  
  116.             continue;  
  117.         }  
  118.         const double inverse_document_freq = ComputeWordInverseDocumentFreq(word);  
  119.         for (const auto [document_id, term_freq] : word_to_document_freqs_.at(word))  
  120.         {  
  121.             const auto& document_data = documents_.at(document_id);  
  122.             if (document_predicate(document_id, document_data.status, document_data.rating))  
  123.             {  
  124.                 document_to_relevance[document_id] += term_freq * inverse_document_freq;  
  125.             }  
  126.  
  127.         }  
  128.     }  
  129.  
  130.     for (const std::string& word : query.minus_words)  
  131.     {  
  132.         if (word_to_document_freqs_.count(word) == 0)  
  133.         {  
  134.             continue;  
  135.         }  
  136.         for (const auto [document_id, _] : word_to_document_freqs_.at(word))  
  137.         {  
  138.             document_to_relevance.erase(document_id);  
  139.         }  
  140.     }  
  141.  
  142.     std::vector<Document> matched_documents;  
  143.    
  144.     for (const auto [document_id, relevance] : document_to_relevance)  
  145.     {  
  146.  
  147.         matched_documents.push_back(  
  148.             { document_id, relevance, documents_.at(document_id).rating });  
  149.  
  150.     }  
  151.     return matched_documents;  
  152. }  
  153.  
  154. template <typename StringContainer>  
  155. SearchServer::SearchServer(const StringContainer& stop_words)  
  156.     : stop_words_(MakeUniqueNonEmptyStrings(stop_words)) // Extract non-empty stop words  
  157. {  
  158.     if (!all_of(stop_words_.begin(), stop_words_.end(), IsValidWord))  
  159.     {  
  160.         throw std::invalid_argument("Some of stop words are invalid"s);  
  161.     }  
  162. }  
  163.  
  164.  
  165.  
  166.  
  167. template <typename DocumentPredicate>  
  168. std::vector<Document> SearchServer::FindTopDocuments(const std::string& raw_query,  
  169.     DocumentPredicate document_predicate) const  
  170. {  
  171.     const auto query = ParseQuery(raw_query);  
  172.  
  173.     auto matched_documents = FindAllDocuments(query, document_predicate);  
  174.  
  175.     sort(matched_documents.begin(), matched_documents.end(),  
  176.         [](const Document& lhs, const Document& rhs)  
  177.         {  
  178.             if (std::abs(lhs.relevance - rhs.relevance) < std::numeric_limits<double>::epsilon())  
  179.             {  
  180.                 return lhs.rating > rhs.rating;  
  181.             }  
  182.             else  
  183.             {  
  184.                 return lhs.relevance > rhs.relevance;  
  185.             }  
  186.         });  
  187.     if (matched_documents.size() > MAX_RESULT_DOCUMENT_COUNT)  
  188.     {  
  189.         matched_documents.resize(MAX_RESULT_DOCUMENT_COUNT);  
  190.     }  
  191.     return matched_documents;  
  192. }  
Advertisement
Add Comment
Please, Sign In to add comment