Advertisement
oster_man

SearchServer.cpp

Aug 13th, 2023
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.50 KB | None | 0 0
  1. #include "search_server.h"
  2. #include <iterator>
  3. #include <chrono>
  4. #include <thread>
  5.  
  6. using namespace std;
  7.  
  8. void AddDocument(SearchServer& server, int document_id, const std::string_view document, DocumentStatus status,
  9.                      const std::vector<int>& ratings){
  10.     server.AddDocument(document_id,document,status,ratings);
  11. }
  12.  
  13. // void AddDocument(SearchServer& server, int document_id, const std::string& document, DocumentStatus status,const std::vector<int>& ratings){
  14. //     AddDocument(server, document_id, std::string_view(document), status, ratings);
  15. // }
  16.  
  17. void SearchServer::AddDocument(int document_id, string_view document, DocumentStatus status,
  18.                  const vector<int>& ratings) {
  19.     if(document.empty())
  20.         return;
  21.     if ((document_id < 0) || (documents_.count(document_id) > 0)) {
  22.         throw invalid_argument("Invalid document_id");
  23.     }
  24.  
  25.     data_strings.emplace_back(document);
  26.  
  27.     const auto words = SplitIntoWordsNoStop(data_strings.back());
  28.  
  29.     const double inv_word_count = 1.0 / words.size();
  30.     for (string_view word : words) {
  31.         word_to_document_freqs_[word][document_id] += inv_word_count;
  32.         document_to_word_freqs_[document_id][word] += inv_word_count;
  33.     }
  34.     documents_.emplace(document_id, DocumentData{ComputeAverageRating(ratings), status});
  35.     document_ids_.insert(document_id);
  36. }
  37.  
  38. vector<Document> SearchServer::FindTopDocuments(string_view raw_query, DocumentStatus status) const {
  39.     return FindTopDocuments(
  40.         raw_query, [status](int document_id, DocumentStatus document_status, int rating) {
  41.             return document_status == status;
  42.         });
  43. }
  44.  
  45. vector<Document> SearchServer::FindTopDocuments(string_view raw_query) const {
  46.     return FindTopDocuments(raw_query, DocumentStatus::ACTUAL);
  47. }
  48.  
  49. const std::map<std::string_view, double>& SearchServer::GetWordFrequencies(int document_id) const{
  50.         if (document_to_word_freqs_.count(document_id) != 0)
  51.             return document_to_word_freqs_.at(document_id); //возможно использование только .at(), т.к. const
  52.         else{
  53.             static std::map<std::string_view, double> empty;
  54.             return empty; //возвращает пустой map (см. инициализацию в конструкторе)
  55.             //в противном случае было бы 1. Warning; 2. Невозможность передачи локальной переменной за пределы обл. видимости
  56.         }
  57.     }
  58.  
  59. void SearchServer::RemoveDocument(int document_id){
  60.     if (document_to_word_freqs_.count(document_id) != 0){
  61.         for (auto& [word,doc]:document_to_word_freqs_.at(document_id))
  62.             word_to_document_freqs_.at(word).erase(document_id);
  63.        
  64.         document_to_word_freqs_.erase(document_id); //удаление из map<int,map<string,double>>
  65.         documents_.erase(document_id); //удаление из map<int,DocumentData>
  66.         document_ids_.erase(document_id); //удаление из set<int>
  67.     }
  68. }
  69.  
  70. void SearchServer::RemoveDocument(std::execution::sequenced_policy t_exec, int document_id){
  71.     RemoveDocument(document_id);
  72. }
  73.  
  74. void SearchServer::RemoveDocument(std::execution::parallel_policy t_exec, int document_id){
  75.     if (document_to_word_freqs_.count(document_id) != 0){
  76.         std::vector<string_view> to_delete(document_to_word_freqs_.at(document_id).size());
  77.  
  78.         // std::transform(to_delete.begin(),to_delete.end(),to_delete.begin(),[](const auto word)->const string&{
  79.         //     return string(word.first);
  80.         // });
  81.  
  82.         std::transform(document_to_word_freqs_[document_id].begin(),document_to_word_freqs_[document_id].end(),to_delete.begin(),[](const auto& word){
  83.             return word.first;
  84.         });
  85.  
  86.         std::for_each(t_exec,to_delete.begin(),to_delete.end(),[&](string_view word){
  87.             word_to_document_freqs_[word].erase(document_id);
  88.         });        
  89.        
  90.         document_to_word_freqs_.erase(document_id); //удаление из map<int,map<string,double>>
  91.         documents_.erase(document_id); //удаление из map<int,DocumentData>
  92.         document_ids_.erase(document_id); //удаление из set<int>
  93.     }
  94. }
  95. tuple<vector<string_view>, DocumentStatus> SearchServer::MatchDocument(string_view raw_query,
  96.                                                         int document_id) const {
  97.     if(!document_ids_.count(document_id))
  98.         throw out_of_range("Document don't exists");
  99.    
  100.     const auto query = std::move(ParseQuery(raw_query));
  101.     std::vector<string_view> matched_words;
  102.    
  103.     if (std::any_of(query.minus_words.begin(),query.minus_words.end(),[this,&document_id](string_view word){
  104.         if (!word_to_document_freqs_.count(word)==0)
  105.             if (word_to_document_freqs_.at(word).count(document_id))
  106.                 return true;
  107.             else return false;
  108.         else return false;
  109.         })){
  110.             return {matched_words, documents_.at(document_id).status};
  111.         }
  112.    
  113.     matched_words.reserve(query.plus_words.size());
  114.  
  115.     std::for_each(execution::seq,query.plus_words.begin(),query.plus_words.end(),[this,&document_id,&matched_words](string_view word){
  116.         if (word_to_document_freqs_.count(word) == 0) {
  117.             return;
  118.         }
  119.         else{
  120.             if(word_to_document_freqs_.at(word).count(document_id))
  121.                 return matched_words.push_back(word);
  122.             else
  123.                 return;
  124.         }
  125.     });
  126.  
  127.     //matched_words.resize(distance(matched_words.begin(),it));
  128.     return {matched_words, documents_.at(document_id).status};
  129. }
  130.  
  131. tuple<vector<string_view>, DocumentStatus> SearchServer::MatchDocument(execution::sequenced_policy,string_view raw_query,
  132.                                                         int document_id) const {
  133.     return MatchDocument(raw_query,document_id);
  134. }
  135.  
  136. tuple<vector<string_view>, DocumentStatus> SearchServer::MatchDocument(std::execution::parallel_policy,string_view raw_query,
  137.                                                         int document_id) const {
  138.     if(!document_ids_.count(document_id))
  139.         throw out_of_range("Document don't exists");
  140.    
  141.     const auto query = std::move(ParseQuery(execution::par,raw_query));
  142.    
  143.     std::vector<string_view> matched_words;
  144.  
  145.     if (std::any_of(execution::par,query.minus_words.begin(),query.minus_words.end(),[this,&document_id](string_view word){
  146.         if (!word_to_document_freqs_.count(std::move(word.substr(1)))==0)
  147.             if (word_to_document_freqs_.at(std::move(word.substr(1))).count(document_id))
  148.                 return true;
  149.             else return false;
  150.         else return false;
  151.         })){
  152.             return {matched_words, documents_.at(document_id).status};
  153.         }
  154.    
  155.     matched_words.resize(query.plus_words.size());
  156.  
  157.     auto it = std::copy_if(execution::par,query.plus_words.begin(),query.plus_words.end(),matched_words.begin(),[this,&document_id](string_view word){
  158.         if (word_to_document_freqs_.count(word) == 0) {
  159.             return false;
  160.         }
  161.         else{
  162.             if(word_to_document_freqs_.at(word).count(document_id))
  163.                 return true;
  164.             else
  165.                 return false;
  166.         }
  167.     });
  168.  
  169.     sort(matched_words.begin(),it);
  170.  
  171.     matched_words.erase(unique(matched_words.begin(),it),matched_words.end());
  172.  
  173.     //matched_words.resize(distance(matched_words.begin(),it));
  174.  
  175.     return {matched_words, documents_.at(document_id).status};
  176. }
  177.  
  178. SearchServer::Query<std::vector<std::string_view>> SearchServer::ParseQuery(string_view text) const {
  179.     Query<std::vector<std::string_view>> result;
  180.     const auto string_query = SplitIntoWords(text);
  181.     result.minus_words.reserve(string_query.size());
  182.     result.plus_words.reserve(string_query.size());
  183.  
  184.     std::for_each (string_query.begin(),string_query.end(),[&result,this](string_view word){
  185.         const auto query_word = std::move(ParseQueryWord(word));
  186.         if (!query_word.is_stop) {
  187.             if (query_word.is_minus) {
  188.                     result.minus_words.push_back(std::move(query_word.data));
  189.             }
  190.             else {
  191.                 result.plus_words.push_back(std::move(query_word.data));
  192.             }
  193.         }
  194.     });
  195.  
  196.     sort(result.minus_words.begin(),result.minus_words.end());
  197.     result.minus_words.erase(unique(execution::seq,result.minus_words.begin(),result.minus_words.end()),result.minus_words.end());
  198.  
  199.     sort(result.plus_words.begin(),result.plus_words.end());
  200.     result.plus_words.erase(unique(execution::seq,result.plus_words.begin(),result.plus_words.end()),result.plus_words.end());
  201.  
  202.     return result;
  203. }
  204.  
  205. SearchServer::Query<std::vector<std::string_view>> SearchServer::ParseQuery(std::execution::sequenced_policy, string_view text) const {
  206.     return ParseQuery(text);
  207. }
  208.  
  209. SearchServer::Query<std::vector<std::string_view>> SearchServer::ParseQuery(std::execution::parallel_policy, string_view text) const {
  210.     Query<std::vector<std::string_view>> result;
  211.     const auto string_query = std::move(SplitIntoWords(text));
  212.  
  213.     result.plus_words.resize(string_query.size());
  214.  
  215.     auto it_plus = std::copy_if(execution::par,string_query.begin(),string_query.end(),result.plus_words.begin(),[&](string_view word){
  216.        const auto query_word = std::move(ParseQueryWord(word));
  217.         return (!query_word.data.empty() && !query_word.is_stop && !query_word.is_minus)?true:false;});
  218.  
  219.     result.plus_words.erase(it_plus,result.plus_words.end());
  220.    
  221.     result.minus_words.resize(string_query.size());
  222.    
  223.     auto it_minus = std::copy_if(execution::par,string_query.begin(),string_query.end(),result.minus_words.begin(),[this](string_view word){
  224.         const auto query_word = std::move(ParseQueryWord(word));
  225.         if ((!query_word.data.empty() && !query_word.is_stop && query_word.is_minus)){
  226.             return true;
  227.         }
  228.         else return false;
  229.         });
  230.  
  231.     result.minus_words.erase(it_minus,result.minus_words.end());
  232.  
  233.     return result;
  234. }
  235.  
  236. std::vector<std::string_view> SearchServer::SplitIntoWordsNoStop(const std::string_view text) const {
  237.     std::vector<std::string_view> words;
  238.     std::vector<std::string_view> temp=std::move(SplitIntoWords(text));
  239.     words.reserve(temp.size());
  240.     using namespace std::string_literals;
  241.     for (const std::string_view word : temp) {
  242.         if (!IsValidWord(word)) {
  243.             throw std::invalid_argument("Word "s + word.data() + " is invalid"s);
  244.         }
  245.         if (!IsStopWord(word)) {
  246.             words.push_back(word);
  247.         }
  248.     }
  249.     return words;
  250. }
  251.  
  252. int SearchServer::ComputeAverageRating(const std::vector<int>& ratings) {
  253.     if (ratings.empty()) {
  254.         return 0;
  255.     }
  256.     int rating_sum = 0;
  257.     for (const int rating : ratings) {
  258.         rating_sum += rating;
  259.     }
  260.     return rating_sum / static_cast<int>(ratings.size());
  261. }
  262.  
  263. SearchServer::QueryWord SearchServer::ParseQueryWord(const std::string_view text) const {
  264.         if (text.empty()) {
  265.             throw std::invalid_argument("Query word is empty"s);
  266.         }
  267.         std::string_view word;
  268.         bool is_minus = false;
  269.         if (text[0] == '-') {
  270.             is_minus = true;
  271.             word = text.substr(1);
  272.         }
  273.         else
  274.             word = text;
  275.         if (word.empty() || word[0] == '-' || !IsValidWord(word)) {
  276.             throw std::invalid_argument("Query word "s + string(text) + " is invalid"s);
  277.         }
  278.  
  279.         return {word, is_minus, IsStopWord(word)};
  280.     }
  281.  
  282.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement