Advertisement
giGii

match_doc

Dec 24th, 2022
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.50 KB | None | 0 0
  1. std::tuple<std::vector<std::string_view>, DocumentStatus> SearchServer::MatchDocument(std::string_view raw_query, int document_id) const {
  2.  
  3.     ThrowSpecialSymbolInText(raw_query);
  4.  
  5.     if (IsNegativeDocumentId(document_id)) {
  6.         throw std::invalid_argument("Negative document id"s);
  7.     }
  8.  
  9.     if (IsNonexistentDocumentId(document_id)) {
  10.         throw std::invalid_argument("Nonexistent document id"s);
  11.     }
  12.  
  13.     SearchServer::PlusMinusWords prepared_query = ParseQuery(raw_query);
  14.  
  15.     for (std::string_view minus_word : prepared_query.minus_words) {
  16.         if (TF_by_term_.count(minus_word) > 0) {
  17.             if (TF_by_term_.at(minus_word).count(document_id) > 0) {
  18.                 return {std::vector<std::string_view>{}, document_info_.at(document_id).status};
  19.             }
  20.         }
  21.     }
  22.  
  23.     std::set<std::string_view> plus_words_in_document;
  24.  
  25.     for (std::string_view plus_word : prepared_query.plus_words) {
  26.         if (TF_by_term_.count(plus_word) == 1) {
  27.             if (TF_by_term_.at(plus_word).count(document_id) == 1) {
  28.                 plus_words_in_document.insert(plus_word);
  29.             }
  30.         }
  31.     }
  32.  
  33.     std::vector<std::string_view> result_intersection; // интересно, если + слов как и - слов в документе не оказалось, пихать неинициализированный result_intersection это нормально?
  34.     for (std::string_view word : plus_words_in_document) {
  35.         result_intersection.push_back(word);
  36.     }
  37.  
  38.     return {result_intersection, document_info_.at(document_id).status};
  39. }
  40.  
  41. std::tuple<std::vector<std::string_view>, DocumentStatus> SearchServer::MatchDocument(std::execution::sequenced_policy, std::string_view raw_query, int document_id) const {
  42.     return MatchDocument(raw_query, document_id);
  43. }
  44.  
  45. std::tuple<std::vector<std::string_view>, DocumentStatus> SearchServer::MatchDocument(std::execution::parallel_policy, std::string_view raw_query, int document_id) const {
  46.  
  47.     if (IsNegativeDocumentId(document_id)) {
  48.         throw std::invalid_argument("Negative document id"s);
  49.     }
  50.  
  51.     if (IsNonexistentDocumentId(document_id)) {
  52.         throw std::invalid_argument("Nonexistent document id"s);
  53.     }
  54.  
  55.     // тут два вектора с возможно повторяющимися + и - словами
  56.     SearchServer::PlusMinusWords prepared_query = ParseQuery(std::execution::par, raw_query);
  57.  
  58.     // вытягиваю слова документа из сервера, других вариантов кроме как по map пройтись у меня нет
  59.     std::vector<std::string_view> words(TF_by_id_.at(document_id).size());
  60.     std::transform(std::execution::par,
  61.                    TF_by_id_.at(document_id).begin(), TF_by_id_.at(document_id).end(),
  62.                    words.begin(),
  63.                    [](auto& item) { return item.first; });
  64.  
  65.     bool is_minus_words_in_document = any_of(std::execution::par, words.begin(), words.end(),
  66.                                              [&prepared_query](std::string_view word) {
  67.  
  68.                                                 return count(std::execution::par, // у меня же теперь вектор! запускаю параллельный ЛИНЕЙНЫЙ поиск (а был set, где поиск шел за log); ПОЧЕМУ БЫСТРЕЕ-ТО ВЫХОДИТ?!
  69.                                                              prepared_query.minus_words.begin(),
  70.                                                              prepared_query.minus_words.end(),
  71.                                                              word);
  72.                                              }
  73.                                             );
  74.  
  75.     if (is_minus_words_in_document) {
  76.         return {std::vector<std::string_view>{}, document_info_.at(document_id).status};
  77.     }
  78.  
  79.     std::vector<std::string_view> result_intersection(std::min(prepared_query.plus_words.size(), words.size()));
  80.     std::copy_if(std::execution::par, words.begin(), words.end(),
  81.                  result_intersection.begin(),
  82.                  [&prepared_query](std::string_view word) {
  83.  
  84.                     return count(std::execution::par,
  85.                                  prepared_query.plus_words.begin(),
  86.                                  prepared_query.plus_words.end(),
  87.                                  word);
  88.                  }
  89.                 );
  90.    
  91.     std::sort(std::execution::par,
  92.               result_intersection.begin(), result_intersection.end());
  93.    
  94.     // найдем первое не пустое слово
  95.     auto start = std::upper_bound(result_intersection.begin(), result_intersection.end(), ""sv);
  96.  
  97.     // // вариант 1: seq=1494, par=998
  98.     // std::vector<std::string> result;
  99.     // std::move(start, result_intersection.end(), std::back_inserter(result));
  100.     // return {result, document_info_.at(document_id).status};
  101.  
  102.     // вариант 2: seq=1503, par=992
  103.     return {{start, result_intersection.end()}, document_info_.at(document_id).status};
  104.  
  105.     // // вариант 3: seq=1444, par=998
  106.  
  107.     // auto last = std::unique(result_intersection.begin(), result_intersection.end());
  108.     // result_intersection.erase(last, result_intersection.end());
  109.     // if (result_intersection.front() == ""sv) {
  110.     //     result_intersection.erase(result_intersection.begin()); // стереть пустую строку из начала
  111.     // }
  112.     // return {result_intersection, document_info_.at(document_id).status};
  113. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement