Advertisement
RobertDeMilo

Ранжирование по релевантности

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