Advertisement
RobertDeMilo

Ускоряем поиск документов

Oct 18th, 2023
217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.31 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <set>
  4. #include <string>
  5. #include <utility>
  6. #include <vector>
  7. #include <map>
  8.  
  9. using namespace std;
  10.  
  11. const int MAX_RESULT_DOCUMENT_COUNT = 5;
  12.  
  13. //Для хранения запроса удобно создать структуру Query с двумя множествами слов : плюс - и минус - словами.
  14. //Возвращать эту структуру по строке запроса нужно в новом приватном методе — ParseQuery.
  15.  
  16. string ReadLine() {
  17.     string s;
  18.     getline(cin, s);
  19.     return s;
  20. }
  21.  
  22. int ReadLineWithNumber() {
  23.     int result = 0;
  24.     cin >> result;
  25.     ReadLine();
  26.     return result;
  27. }
  28.  
  29. vector<string> SplitIntoWords(const string& text) {
  30.     vector<string> words;
  31.     string word;
  32.     for (const char c : text) {
  33.         if (c == ' ') {
  34.             if (!word.empty()) {
  35.                 words.push_back(word);
  36.                 word.clear();
  37.             }
  38.         }
  39.         else {
  40.             word += c;
  41.         }
  42.     }
  43.     if (!word.empty()) {
  44.         words.push_back(word);
  45.     }
  46.  
  47.     return words;
  48. }
  49.  
  50. struct Document {
  51.     int id;
  52.     int relevance;
  53. };
  54.  
  55. class SearchServer {
  56. public:
  57.     void SetStopWords(const string& text) {
  58.         for (const string& word : SplitIntoWords(text)) {
  59.             stop_words_.insert(word);
  60.         }
  61.     }
  62.     // В методе AddDocument переберите слова документа, кроме стоп - слов.
  63.     // В множество документов, соответствующих очередному слову, вставьте id текущего документа.
  64.  
  65.     void AddDocument(int document_id, const string& document) {
  66.  
  67.         //const vector<string> words = SplitIntoWordsNoStop(document);
  68.  
  69.         //documents_.push_back({ document_id, words });
  70.        
  71.         for (const string& word : SplitIntoWordsNoStop(document))
  72.         {
  73.             documents_[word].insert(document_id);
  74.         }
  75.     }
  76.  
  77.     vector<Document> FindTopDocuments(const string& raw_query) const {
  78.  
  79.         const Query query_words = ParseQuery(raw_query);
  80.  
  81.         auto matched_documents = FindAllDocuments(query_words);
  82.  
  83.         sort(matched_documents.begin(), matched_documents.end(),
  84.             [](const Document& lhs, const Document& rhs) {
  85.                 return lhs.relevance > rhs.relevance;
  86.             });
  87.         if (matched_documents.size() > MAX_RESULT_DOCUMENT_COUNT) {
  88.             matched_documents.resize(MAX_RESULT_DOCUMENT_COUNT);
  89.         }
  90.         return matched_documents;
  91.     }
  92.  
  93. private:
  94.     // больше не понадобится
  95.     /*struct DocumentContent {
  96.         int id = 0;
  97.         vector<string> words;
  98.     };  
  99.     vector<DocumentContent> documents_;*/
  100.  
  101.     // Ключи этого контейнера — слова из добавленных документов,
  102.     // а значения — id документов, в которых это слово встречается.
  103.  
  104.     map<string, set<int>> documents_;// new
  105.  
  106.     struct Query
  107.     {
  108.         set<string> plus_words;
  109.         set<string> minus_words;
  110.     };
  111.  
  112.     set<string> stop_words_;
  113.  
  114.     bool IsStopWord(const string& word) const {
  115.         return stop_words_.count(word) > 0;
  116.     }
  117.  
  118.     vector<string> SplitIntoWordsNoStop(const string& text) const {
  119.         vector<string> words;
  120.         for (const string& word : SplitIntoWords(text)) {
  121.             if (!IsStopWord(word)) {
  122.                 words.push_back(word);
  123.             }
  124.         }
  125.         return words;
  126.     }
  127.  
  128.     /*set<string> ParseQuery(const string& text) const*/
  129.     Query ParseQuery(const string& text) const
  130.     {
  131.         /*set<string> query_words;*/
  132.         Query query;
  133.  
  134.         for (const string& word : SplitIntoWordsNoStop(text)) {
  135.  
  136.             if (word[0] == '-')
  137.             {
  138.                 query.minus_words.insert(word.substr(1));
  139.             }
  140.  
  141.             else
  142.             {
  143.                 query.plus_words.insert(word);
  144.             }
  145.         }
  146.         return query;
  147.     }
  148.  
  149.     //В методе FindAllDocuments сначала вычислите релевантность документов, в которые входят плюс - слова запроса.
  150.     //Для этого используйте map<int, int>,  где ключ — id документа, а значение — количество плюс-слов,
  151.     // которые в этом документе встречаются.Затем исключите из получившегося map те документы,
  152.     //в которых встретилось хотя бы одно минус - слово.
  153.    
  154.     //Оставшиеся элементы map скопируйте в результирующий vector<Document>.
  155.  
  156.     /*vector<Document> FindAllDocuments(const set<string>& query_words) const*/
  157.     vector<Document> FindAllDocuments(const Query& query_words) const
  158.     {
  159.         /*for (const auto& document : documents_)
  160.         {
  161.             const int relevance = MatchDocument(document, query_words);
  162.             if (relevance > 0)
  163.             {
  164.                 matched_documents.push_back({ document.id, relevance });
  165.             }
  166.         }*/
  167.  
  168.         // [id количество плюс - слов]
  169.         map<int, int> id_relevance;
  170.  
  171.         vector<Document> matched_documents;
  172.  
  173.         //бежим по плюс - словам
  174.         for (const string& word : query_words.plus_words)
  175.         {
  176.             if (documents_.count(word) != 0)
  177.             {
  178.                 for (const auto& id : documents_.at(word))  // метод константный поэтому at
  179.                 {
  180.                     ++id_relevance[id];
  181.                 }
  182.             }
  183.         }
  184.  
  185.         vector <int> id_with_minus_words;
  186.         //бежим по минус - словам
  187.         for (const string& word : query_words.minus_words)
  188.         {
  189.             if (documents_.count(word) != 0)
  190.             {
  191.                 for (const auto& id : documents_.at(word))   // метод константный поэтому at
  192.                 {
  193.                     id_with_minus_words.push_back(id);
  194.                 }
  195.             }
  196.         }
  197.  
  198.         //удаляем id с минус - словами
  199.         for (const auto& id : id_with_minus_words)
  200.         {
  201.             id_relevance.erase(id);
  202.         }
  203.  
  204.         for (const auto& [id,rel] : id_relevance)
  205.         {
  206.             matched_documents.push_back({ id,rel });
  207.         }
  208.  
  209.         return matched_documents;
  210.     }
  211.        
  212. };
  213.  
  214. SearchServer CreateSearchServer() {
  215.     SearchServer search_server;
  216.     search_server.SetStopWords(ReadLine());
  217.  
  218.     const int document_count = ReadLineWithNumber();
  219.     for (int document_id = 0; document_id < document_count; ++document_id) {
  220.         search_server.AddDocument(document_id, ReadLine());
  221.     }
  222.  
  223.     return search_server;
  224. }
  225.  
  226. int main() {
  227.     const SearchServer search_server = CreateSearchServer();
  228.  
  229.     const string query = ReadLine();
  230.     for (const auto& [document_id, relevance] : search_server.FindTopDocuments(query)) {
  231.         cout << "{ document_id = "s << document_id << ", "
  232.             << "relevance = "s << relevance << " }"s << endl;
  233.     }
  234. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement