shizaero

Untitled

Aug 31st, 2023
695
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.74 KB | None | 0 0
  1. #include "search_server.h"  
  2. using namespace std;  
  3.  
  4.  
  5. std::vector<int>::iterator SearchServer::begin()  
  6. {  
  7.     return document_ids_.begin();  
  8. }  
  9.  
  10. std::vector<int>::const_iterator SearchServer::begin() const  
  11. {  
  12.     return document_ids_.begin();  
  13. }  
  14.  
  15. std::vector<int>::iterator SearchServer::end()  
  16. {  
  17.     return document_ids_.end();  
  18. }  
  19.  
  20. std::vector<int>::const_iterator SearchServer::end() const  
  21. {  
  22.     return document_ids_.end();  
  23. }  
  24.  
  25. const map<string, double>& SearchServer::GetWordFrequencies(int document_id) const {  
  26.     static const std::map<std::string, double> dummy;  
  27.  
  28.     if (document_to_word_freqs_.find(document_id) != document_to_word_freqs_.end()) {  
  29.         return document_to_word_freqs_.at(document_id);  
  30.     }  
  31.     return dummy;  
  32. }  
  33.  
  34. void SearchServer::RemoveDocument(int document_id)  
  35. {  
  36.     if (documents_.count(document_id) <= 0) return;
  37.         documents_.erase(document_id);  
  38.         for (auto& word_freqs : word_to_document_freqs_)  
  39.         {  
  40.             word_freqs.second.erase(document_id);  
  41.         }  
  42.  
  43.         document_to_word_freqs_.erase(document_id);  
  44.         document_ids_.erase(std::remove(document_ids_.begin(), document_ids_.end(), document_id), document_ids_.end());  
  45. }  
  46.  
  47. void SearchServer::RemoveDocument(std::execution::sequenced_policy policy, int document_id){
  48.     RemoveDocument(document_id);
  49. }
  50.     void SearchServer::RemoveDocument(std::execution::parallel_policy policy, int document_id){
  51.        
  52.         vector<const string*> temp;
  53.         transform(policy, word_to_document_freqs_.begin(), word_to_document_freqs_.end(), temp.begin(),
  54.                  [document_id](const auto& element){
  55.                      if(element.second.first == document_id){
  56.                          return element.first;
  57.                      }
  58.                  });
  59.         document_to_word_freqs_.erase(document_id);  
  60.         document_ids_.erase(std::remove(document_ids_.begin(), document_ids_.end(), document_id), document_ids_.end());
  61.  
  62.     }
  63.  
  64. SearchServer::SearchServer(const std::string& stop_words_text)  
  65.     : SearchServer(SplitIntoWords(stop_words_text)) // Invoke delegating constructor from string container  
  66. {  
  67. }  
  68.  
  69. void SearchServer::AddDocument(int document_id, const string& document, DocumentStatus status, const vector<int>& ratings)  
  70. {  
  71.     if ((document_id < 0) || (documents_.count(document_id) > 0))  
  72.     {  
  73.         throw invalid_argument("Invalid document_id"s);  
  74.     }  
  75.     const auto words = SplitIntoWordsNoStop(document);  
  76.     const double inv_word_count = 1.0 / words.size();  
  77.     for (const string& word : words)  
  78.     {  
  79.         word_to_document_freqs_[word][document_id] += inv_word_count;  
  80.         document_to_word_freqs_[document_id][word] += inv_word_count;  
  81.     }  
  82.     documents_.emplace(document_id, DocumentData{ ComputeAverageRating(ratings), status});  
  83.     document_ids_.push_back(document_id);  
  84. }  
  85.  
  86. vector<Document> SearchServer::FindTopDocuments(const string& raw_query, DocumentStatus status) const  
  87. {  
  88.     return FindTopDocuments(  
  89.         raw_query, [status](int document_id, DocumentStatus document_status, int rating)  
  90.         { return document_status == status; });  
  91. }  
  92.  
  93. vector<Document> SearchServer::FindTopDocuments(const string& raw_query) const  
  94. {  
  95.     return FindTopDocuments(raw_query, DocumentStatus::ACTUAL);  
  96. }  
  97.  
  98. int SearchServer::GetDocumentCount() const  
  99. {  
  100.     return static_cast<int>(documents_.size());  
  101. }  
  102.  
  103.  
  104. tuple<vector<string>, DocumentStatus> SearchServer::MatchDocument(const string& raw_query, int document_id) const  
  105. {  
  106.     const auto query = ParseQuery(raw_query);  
  107.     vector<string> matched_words;  
  108.     for (const string& word : query.plus_words)  
  109.     {  
  110.         if (word_to_document_freqs_.count(word) == 0)  
  111.         {  
  112.             continue;  
  113.         }
  114.         if (word_to_document_freqs_.at(word).count(document_id))  
  115.         {  
  116.             matched_words.push_back(word);  
  117.         }  
  118.     }  
  119.     for (const string& word : query.minus_words)  
  120.     {  
  121.         if (word_to_document_freqs_.count(word) == 0)  
  122.         {  
  123.             continue;  
  124.         }  
  125.         if (word_to_document_freqs_.at(word).count(document_id))  
  126.         {  
  127.             matched_words.clear();  
  128.             break;  
  129.         }  
  130.     }  
  131.     return { matched_words, documents_.at(document_id).status };  
  132. }  
  133.  
  134. bool SearchServer::IsValidWord(const std::string& word)  
  135. {  
  136.     // A valid word must not contain special characters  
  137.     return none_of(word.begin(), word.end(), [](char c)  
  138.         { return c >= '\0' && c < ' '; });  
  139. }  
  140.  
  141. bool SearchServer::IsStopWord(const string& word) const  
  142. {  
  143.     return stop_words_.count(word) > 0;  
  144. }  
  145.  
  146. vector<string> SearchServer::SplitIntoWordsNoStop(const string& text) const  
  147. {  
  148.     vector<string> words;  
  149.     for (const string& word : SplitIntoWords(text))  
  150.     {  
  151.         if (!IsValidWord(word))  
  152.         {  
  153.             throw invalid_argument("Word "s + word + " is invalid"s);  
  154.         }  
  155.         if (!IsStopWord(word))  
  156.         {  
  157.             words.push_back(word);  
  158.         }  
  159.     }  
  160.  
  161.     return words;  
  162. }  
  163.  
  164. int SearchServer::ComputeAverageRating(const std::vector<int>& ratings)  
  165. {  
  166.     if (ratings.empty())  
  167.     {  
  168.         return 0;  
  169.     }  
  170.     int rating_sum = accumulate(ratings.begin(), ratings.end(), 0);  
  171.     return rating_sum / static_cast<int>(ratings.size());  
  172. }  
  173.  
  174. SearchServer::QueryWord SearchServer::ParseQueryWord(const string& text) const  
  175. {  
  176.     if (text.empty())  
  177.     {  
  178.         throw invalid_argument("Query word is empty"s);  
  179.     }  
  180.  
  181.     string word = text;  
  182.     bool is_minus = false;  
  183.     if (word[0] == '-')  
  184.     {  
  185.         is_minus = true;  
  186.         word = word.substr(1);  
  187.     }  
  188.     if (word.empty() || word[0] == '-' || !IsValidWord(word))  
  189.     {  
  190.         throw invalid_argument("Query word "s + text + " is invalid");
  191.     }  
  192.     return { word, is_minus, IsStopWord(word) };  
  193. }  
  194.  
  195. SearchServer::Query SearchServer::ParseQuery(const string& text) const  
  196. {  
  197.     Query result;  
  198.     for (const string& word : SplitIntoWords(text))  
  199.     {  
  200.         const auto query_word = ParseQueryWord(word);  
  201.         if (!query_word.is_stop)  
  202.         {  
  203.             if (query_word.is_minus)  
  204.             {  
  205.                 result.minus_words.insert(query_word.data);  
  206.             }  
  207.             else  
  208.             {  
  209.                 result.plus_words.insert(query_word.data);  
  210.             }  
  211.         }  
  212.     }  
  213.     return result;  
  214. }  
  215.  
  216. double SearchServer::ComputeWordInverseDocumentFreq(const string& word) const  
  217. {  
  218.     return log(GetDocumentCount() * 1.0 / word_to_document_freqs_.at(word).size());  
  219. }  
Advertisement
Add Comment
Please, Sign In to add comment