Punchcard

Untitled

May 17th, 2023
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.49 KB | Source Code | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <set>
  4. #include <map>
  5. #include <string>
  6. #include <utility>
  7. #include <vector>
  8. #include <cmath>
  9.  
  10. using namespace std;
  11.  
  12. const int MAX_RESULT_DOCUMENT_COUNT = 5;
  13.        
  14.  
  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.         } else {
  39.             word += c;
  40.         }
  41.     }
  42.     if (!word.empty()) {
  43.         words.push_back(word);
  44.     }
  45.  
  46.     return words;
  47. }
  48.  
  49. struct Document {
  50.     int id;
  51.     double relevance;
  52. };
  53.  
  54. class SearchServer {
  55. public:
  56.     void dumpMatchedDocuments(const vector<Document>& matched_documents, string msg = ""s) const {
  57.        
  58.         cout << msg << endl;
  59.         for (auto& [doc_id, relevance] : matched_documents) {
  60.             cout << "doc_id="s << doc_id << ", relevance="s << relevance << endl;
  61.         }
  62.     }
  63.    
  64.     void SetStopWords(const string& text) {
  65.         for (const string& word : SplitIntoWords(text)) {
  66.             stop_words_.insert(word);
  67.         }
  68.     }
  69.    
  70.     void setDocumentCount(int document_count) {
  71.        
  72.         document_count_ = document_count;
  73.     }
  74.  
  75.     void AddDocument(int document_id, const string& document) {
  76.         const vector<string> words = SplitIntoWordsNoStop(document);
  77.        
  78.         double words_size = words.size();
  79.         for(string word : words) {            
  80.        
  81.             documents_[word].insert({document_id, count(words.begin(), words.end(), word) / words_size});          
  82.         }
  83.     }
  84.  
  85.     vector<Document> FindTopDocuments(const string& raw_query) const {
  86.         const Query query = ParseQuery(raw_query);
  87.         auto matched_documents = FindAllDocuments(query);
  88.  
  89.         sort(matched_documents.begin(), matched_documents.end(),
  90.              [](const Document& lhs, const Document& rhs) {
  91.                  return lhs.relevance > rhs.relevance;
  92.              });
  93.         if (matched_documents.size() > MAX_RESULT_DOCUMENT_COUNT) {
  94.             matched_documents.resize(MAX_RESULT_DOCUMENT_COUNT);
  95.         }
  96.         return matched_documents;
  97.     }
  98.  
  99. private:
  100.  
  101.     struct QueryWord {
  102.         string data;
  103.         bool is_minus;
  104.         bool is_stop;
  105.     };
  106.  
  107.     struct Query {
  108.         set<string> plus_words;
  109.         set<string> minus_words;
  110.     };
  111. //      key      doc_id, relevance(TF)
  112.     map<string, map<int, double>> documents_;  
  113.  
  114.     set<string> stop_words_;   
  115.     int document_count_ = 0;
  116.  
  117.     bool IsStopWord(const string& word) const {
  118.         return stop_words_.count(word) > 0;
  119.     }
  120.  
  121.     vector<string> SplitIntoWordsNoStop(const string& text) const {
  122.         vector<string> words;
  123.         for (const string& word : SplitIntoWords(text)) {
  124.             if (!IsStopWord(word)) {
  125.                 words.push_back(word);
  126.             }
  127.         }
  128.         return words;
  129.     }
  130.  
  131.     QueryWord ParseQueryWord(string text) const {
  132.         bool is_minus = false;
  133.         // Word shouldn't be empty
  134.         if (text[0] == '-') {
  135.             is_minus = true;
  136.             text = text.substr(1);
  137.         }
  138.         return {text, is_minus, IsStopWord(text)};
  139.     }
  140.  
  141.     Query ParseQuery(const string& text) const {
  142.         Query query;
  143.         for (const string& word : SplitIntoWords(text)) {
  144.             const QueryWord query_word = ParseQueryWord(word);
  145.             if (!query_word.is_stop) {
  146.                 if (query_word.is_minus) {
  147.                     query.minus_words.insert(query_word.data);
  148.                 } else {
  149.                     query.plus_words.insert(query_word.data);
  150.                 }
  151.             }
  152.         }
  153.         return query;
  154.     }  
  155.  
  156.     vector<Document> FindAllDocuments(const Query& query) const {
  157.    
  158.         vector<Document> matched_documents;
  159.         map<string, map<int, double>> relevance;
  160.         map<int, double> tfs;
  161.        
  162.         for (const string& plus_word : query.plus_words) {
  163.             if(documents_.count(plus_word) == 0) continue;         
  164.            
  165.             double  doc_number = documents_.at(plus_word).size();              
  166.             double idf = log(document_count_ / doc_number);
  167.            
  168.             for(const auto& [doc_id, tf] : documents_.at(plus_word)) {
  169.                 tfs[doc_id] += tf * idf;               
  170.             }          
  171.         }
  172.        
  173.         for (const string& minus_word : query.minus_words) {
  174.             if(documents_.count(minus_word) == 0) continue;
  175.             const map<int, double> doc_map_minus = documents_.at(minus_word);          
  176.             for(const auto& [doc_id, tf] : doc_map_minus) {
  177.                 tfs.erase(doc_id);
  178.             }          
  179.         }      
  180.        
  181.         for (const auto& [doc_id, rel] : tfs) {
  182.            
  183.             matched_documents.push_back({doc_id, rel});        
  184.         }      
  185.         return matched_documents;
  186.     }
  187.  
  188. };
  189.  
  190. //*
  191. SearchServer CreateSearchServer() {
  192.     SearchServer search_server;
  193.     search_server.SetStopWords(ReadLine());
  194.  
  195.     const int document_count = ReadLineWithNumber();
  196.     for (int document_id = 0; document_id < document_count; ++document_id) {
  197.         search_server.AddDocument(document_id, ReadLine());
  198.     }
  199.     search_server.setDocumentCount(document_count);
  200.     return search_server;
  201. }
  202.  
  203. int main() {
  204.     const SearchServer search_server = CreateSearchServer();
  205.  
  206.     const string query = ReadLine();
  207.     for (const auto& [document_id, relevance] : search_server.FindTopDocuments(query)) {
  208.         cout << "{ document_id = "s << document_id << ", "
  209.              << "relevance = "s << relevance << " }"s << endl;
  210.     }
  211. }
  212. //*/
  213. /*
  214.  
  215. SearchServer CreateSearchServer() {
  216.     SearchServer search_server;
  217.     search_server.SetStopWords("is are was a an in the with near at"s);
  218.    
  219.     vector<pair<int, string>> in_docs = {
  220.         {0, "a colorful parrot with green wings and red tail is lost"s},
  221.         {1, "a grey hound with black ears is found at the railway station"s},
  222.         {2, "a white cat with long furry tail is found near the red square"s}
  223.     };
  224.    
  225.     for (auto [document_id, line] : in_docs) {
  226.         search_server.AddDocument(document_id, line);
  227.     }
  228.  
  229.  
  230.     const int document_count = 3;
  231.  
  232.     search_server.setDocumentCount(document_count);
  233.     return search_server;
  234. }
  235.  
  236. int main() {
  237.     SearchServer search_server = CreateSearchServer();
  238.  
  239.     const string query = "white cat long tail"s;
  240.     for (const auto& [document_id, relevance] : search_server.FindTopDocuments(query)) {
  241.         cout << "{ document_id = "s << document_id << ", "
  242.              << "relevance = "s << relevance << " }"s << endl;
  243.     }
  244. }
  245. //*/
Advertisement
Add Comment
Please, Sign In to add comment