Advertisement
RobertDeMilo

мое красивое решение count в counte как устроены шаблоны

Oct 22nd, 2023
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.34 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <vector>
  4. #include <cmath>
  5. #include <map>
  6.  
  7. using namespace std;
  8.  
  9. //Задание
  10. //Реализуйте шаблонную функцию ComputeTfIdfs, которая вычисляет TF - IDF заданного слова для каждого документа из набора.
  11. //Первый параметр documents — контейнер документов.циклом for (const auto& document : documents) можно перебрать все документы в нём, а в каждом документе — все слова.Тип слова, документа и набора документов может быть произвольным — ваша функция должна быть готова к любым, если есть возможность итерирования.
  12. //Гарантируется, что и набор документов, и каждый отдельный документ имеют методы begin, end и size.Например, документом может быть строка, а словом — символ.
  13. //Второй параметр term — слово, у которого нужно вычислить TF - IDF.Его тип совпадает с типом слов, которые получаются при итерировании по документу.
  14. //Функция должна вернуть вектор вещественных чисел, который совпадает по длине с количеством документов.В первом элементе должен лежать TF - IDF слова term для первого документа, в последнем элементе — TF - IDF слова term для последнего документа.
  15. //Напоминаем, что TF - IDF — это произведение TF и IDF.TF слова term в документе — доля слов документа, совпадающих с term.IDF вычисляется для слова независимо от конкретного документа и равен логарифму(функция log из <cmath>) от documents.size() / document_freq, где знаменатель — это количество документов, содержащих term.
  16. //Пример из тренажёра должен вывести 0.081093 0.101366 0.
  17.  
  18.  
  19. template <typename Documents, typename Term>
  20. vector<double> ComputeTfIdfs(const Documents& documents, const Term& term)
  21. {
  22.     vector<double> relevances;
  23.  
  24.     map<int, double> ID_TF;
  25.  
  26.     int counter = 0;
  27.  
  28.     for (const auto& document : documents)
  29.     {
  30.         double TF = 1.0 * count(document.begin(), document.end(), term) / document.size();
  31.  
  32.         ID_TF[counter] = TF;
  33.  
  34.         ++counter;
  35.     }
  36.                                                                           *Важно именно auto для шаблонной функции!*
  37.                                                                                *********************************************************************************************************************
  38.     double IDF = log(1.0 * documents.size() / (count_if(documents.begin(), documents.end(), [term](const auto& doc)
  39.         {
  40.             return count(doc.begin(), doc.end(), term);
  41.         }
  42.     )));
  43. *********************************************************************************************************************
  44.     for (const auto& [id, TF] : ID_TF)
  45.     {
  46.         relevances.push_back(TF * IDF);
  47.     }
  48.  
  49.     return relevances;
  50. }
  51.  
  52. int main()
  53. {
  54.     const vector<vector<string>> documents = {
  55.         {"белый"s, "кот"s, "и"s, "модный"s, "ошейник"s},
  56.         {"пушистый"s, "кот"s, "пушистый"s, "хвост"s},
  57.         {"ухоженный"s, "пёс"s, "выразительные"s, "глаза"s},
  58.     };
  59.     const auto& tf_idfs = ComputeTfIdfs(documents, "кот"s);
  60.  
  61.     for (const double tf_idf : tf_idfs)
  62.     {
  63.         cout << tf_idf << " "s;
  64.     }
  65.     cout << endl;
  66.     return 0;
  67. }
  68. *********************************************************************************************************************
  69. Авторское решение
  70. #include <algorithm>
  71. #include <cmath>
  72. #include <iostream>
  73. #include <vector>
  74.  
  75. using namespace std;
  76.  
  77. template <typename Documents, typename Term>
  78. vector<double> ComputeTfIdfs(const Documents& documents, const Term& term) {
  79.     vector<double> tf_idfs;
  80.  
  81.     int document_freq = 0;
  82.     for (const auto& document : documents) {
  83.         const int freq = count(document.begin(), document.end(), term);
  84.         if (freq > 0) {
  85.             ++document_freq;
  86.         }
  87.         tf_idfs.push_back(static_cast<double>(freq) / document.size());
  88.     }
  89.  
  90.     const double idf = log(static_cast<double>(documents.size()) / document_freq);
  91.     for (double& tf_idf : tf_idfs) {
  92.         tf_idf *= idf;
  93.     }
  94.  
  95.     return tf_idfs;
  96. }
  97.  
  98. int main() {
  99.     const vector<vector<string>> documents = {
  100.         {"белый"s, "кот"s, "и"s, "модный"s, "ошейник"s},
  101.         {"пушистый"s, "кот"s, "пушистый"s, "хвост"s},
  102.         {"ухоженный"s, "пёс"s, "выразительные"s, "глаза"s},
  103.     };
  104.     const auto& tf_idfs = ComputeTfIdfs(documents, "кот"s);
  105.     for (const double tf_idf : tf_idfs) {
  106.         cout << tf_idf << " "s;
  107.     }
  108.     cout << endl;
  109.     return 0;
  110. }
  111.  
  112.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement