Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "search_server.h"
- #include <iostream>
- using namespace std;
- SearchServer::SearchServer(const string& stop_words_text)
- : SearchServer(SplitIntoWords(stop_words_text)) // Invoke delegating constructor from string container
- {
- }
- void SearchServer::AddDocument(int document_id, const string& document, DocumentStatus status,
- const vector<int>& ratings) {
- if (documents_.count(document_id) > 0) {
- throw invalid_argument("�������� � ����� id ��� ����������."s);
- } else if (document_id < 0) {
- throw invalid_argument("�������� �� ����� ����� ������������� id."s);
- } else if (!IsValidWord(document)) {
- throw invalid_argument("���������� ��������� �������� ������������ �������"s);
- }
- const vector<string> words = SplitIntoWordsNoStop(document);
- //words_in_documents_[document_id] = words;
- const double inv_word_count = 1.0 / words.size();
- for (const string& word : words) {
- word_to_document_freqs_[word][document_id] += inv_word_count;
- //words_in_documents_[document_id].push_back(word);
- word_frequencies_in_document_[document_id][word] += inv_word_count;
- }
- documents_.emplace(document_id, DocumentData{ ComputeAverageRating(ratings), status });
- order_addition_document_.insert(document_id);
- }
- vector<Document> SearchServer::FindTopDocuments(const std::string& raw_query, DocumentStatus status) const {
- return FindTopDocuments(raw_query, [status](int document_id, DocumentStatus document_status, int rating) {
- return document_status == status;
- });
- }
- vector<Document> SearchServer::FindTopDocuments(const std::string& raw_query) const {
- return FindTopDocuments(raw_query, DocumentStatus::ACTUAL);
- }
- int SearchServer::GetDocumentCount() const {
- return documents_.size();
- }
- const map<string, double>& SearchServer::GetWordFrequencies(int document_id) const {
- if (!documents_.count(document_id)) {
- return empty_;
- }
- return word_frequencies_in_document_.at(document_id);
- }
- set<int>::const_iterator SearchServer::begin() {
- return order_addition_document_.begin();
- }
- set<int>::const_iterator SearchServer::end() {
- return order_addition_document_.end();
- }
- void SearchServer::RemoveDocument(int document_id) {
- SearchServer::RemoveDocument(execution::seq, document_id);
- }
- void SearchServer::RemoveDocument(execution::sequenced_policy, int document_id) {
- if (!documents_.count(document_id)) {
- throw invalid_argument("��������� � ��������� id �� ����������.");
- }
- // log(���������� ����������) * ���������� ���� � ��������� ���������,
- // �.�. � ������� ��������� ���� �������
- for (const auto& [word, freq] : word_frequencies_in_document_.at(document_id)) {
- // log(���������� ���� �� ���� ����������)
- word_to_document_freqs_[word].erase(document_id);
- }
- word_frequencies_in_document_.erase(document_id);
- documents_.erase(document_id);
- order_addition_document_.erase(document_id);
- }
- void SearchServer::RemoveDocument(execution::parallel_policy, int document_id) {
- if (!documents_.count(document_id)) {
- throw invalid_argument("��������� � ��������� id �� ����������.");
- }
- // ��� ����������������� for
- map<string, double>& frequency_word_in_each_document = word_frequencies_in_document_.at(document_id); // ������� ���� � ���������
- vector<const string*> words(frequency_word_in_each_document.size()); // ������ ���������� �� �����
- // ������������ �������������� ���������� �� ����� � ������
- transform(execution::par, frequency_word_in_each_document.begin(), frequency_word_in_each_document.end(),
- words.begin(),
- [](const pair<const string&, double>& ptr_to_word) {
- return &ptr_to_word.first;
- });
- // �������� ���������� id �� ���������� � ������ ������
- for_each(execution::par, words.begin(), words.end(),
- [this, document_id](const string* word) {
- word_to_document_freqs_[*word].erase(document_id);
- });
- word_frequencies_in_document_.erase(document_id);
- documents_.erase(document_id);
- order_addition_document_.erase(document_id);
- }
- tuple<vector<string>, DocumentStatus> SearchServer::MatchDocument(const string& raw_query, int document_id) const {
- return MatchDocument(execution::seq, raw_query, document_id);
- }
- tuple<vector<string>, DocumentStatus> SearchServer::MatchDocument(execution::sequenced_policy policy,
- const string& raw_query, int document_id) const {
- //LOG_DURATION_STREAM("MatchDocument"s, cout);
- if (document_id < 0 || word_frequencies_in_document_.count(document_id) == 0) {
- throw out_of_range("��������� � ��������� id �� ����������.");
- }
- const Query query = ParseQuery(raw_query);
- vector<string> matched_words;
- for (const string& word : query.plus_words) {
- if (word_to_document_freqs_.count(word) == 0) {
- continue;
- }
- if (word_to_document_freqs_.at(word).count(document_id)) {
- matched_words.push_back(word);
- }
- }
- for (const string& word : query.minus_words) {
- if (word_to_document_freqs_.count(word) == 0) {
- continue;
- }
- if (word_to_document_freqs_.at(word).count(document_id)) {
- matched_words.clear();
- break;
- }
- }
- return { matched_words, documents_.at(document_id).status };
- }
- tuple<vector<string>, DocumentStatus> SearchServer::MatchDocument(execution::parallel_policy policy,
- const string& raw_query, int document_id) const {
- if (document_id < 0 || word_frequencies_in_document_.count(document_id) == 0) {
- throw out_of_range("��������� � ��������� id �� ����������.");
- }
- Query query = ParseQuery(raw_query, false);
- if (any_of(policy, query.minus_words.begin(), query.minus_words.end(),
- [this, &document_id](const string& minus_word) {
- return word_frequencies_in_document_.at(document_id).count(minus_word);
- })) {
- return {};
- }
- vector<string> matched_words(query.plus_words.size());
- vector<string>::iterator end_new_size = copy_if(policy, query.plus_words.begin(), query.plus_words.end(),
- matched_words.begin(),
- [this, &document_id](const string& plus_word) {
- return word_frequencies_in_document_.at(document_id).count(plus_word);
- });
- matched_words.resize(distance(matched_words.begin(), end_new_size));
- sort(policy, matched_words.begin(), matched_words.end());
- matched_words.erase(unique(policy, matched_words.begin(), matched_words.end()), matched_words.end());
- return { matched_words, documents_.at(document_id).status };
- }
- bool SearchServer::IsStopWord(const string& word) const {
- return stop_words_.count(word) > 0;
- }
- vector<string> SearchServer::SplitIntoWordsNoStop(const string& text) const {
- vector<string> words;
- for (const string& word : SplitIntoWords(text)) {
- if (!IsStopWord(word)) {
- words.push_back(word);
- }
- }
- return words;
- }
- int SearchServer::ComputeAverageRating(const vector<int>& ratings) {
- if (ratings.empty()) {
- return 0;
- }
- int rating_sum = accumulate(ratings.begin(), ratings.end(), 0);
- return rating_sum / static_cast<int>(ratings.size());
- }
- SearchServer::QueryWord SearchServer::ParseQueryWord(string text) const {
- bool is_minus = false;
- // Word shouldn't be empty
- if (text.empty()) {
- throw invalid_argument("������������ ������ ����� � �������.");
- }
- if (text[0] == '-') {
- if (text[1] == '-') {
- throw invalid_argument("������ �������� ��� ����� \"-\" ������.");
- }
- is_minus = true;
- text = text.substr(1);
- }
- return { text, is_minus, IsStopWord(text) };
- }
- SearchServer::Query SearchServer::ParseQuery(const string& text, bool sequenced_policy) const {
- Query query;
- for (const string& word : SplitIntoWords(text)) {
- if (!IsValidWord(word)) {
- throw invalid_argument("������������ ��������� ������.");
- }
- if (word == "-"s) {
- throw invalid_argument("����� ����� \"-\" ����������� �����.");
- }
- QueryWord query_word = ParseQueryWord(word);
- if (!query_word.is_stop) {
- if (query_word.is_minus) {
- query.minus_words.push_back(query_word.data);
- } else {
- query.plus_words.push_back(query_word.data);
- }
- }
- }
- if (sequenced_policy) {
- sort(query.plus_words.begin(), query.plus_words.end());
- query.plus_words.erase(unique(query.plus_words.begin(), query.plus_words.end()), query.plus_words.end());
- sort(query.minus_words.begin(), query.minus_words.end());
- query.minus_words.erase(unique(query.minus_words.begin(), query.minus_words.end()), query.minus_words.end());
- }
- return query;
- }
- double SearchServer::ComputeWordInverseDocumentFreq(const string& word) const {
- return log(GetDocumentCount() * 1.0 / word_to_document_freqs_.at(word).size());
- }
- bool SearchServer::IsValidWord(const string& word) {
- // A valid word must not contain special characters
- return none_of(word.begin(), word.end(), [](char c) {
- return c >= '\0' && c < ' ';
- });
- }
Advertisement
Add Comment
Please, Sign In to add comment