Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "search_server.h"
- using namespace std;
- std::vector<int>::iterator SearchServer::begin()
- {
- return document_ids_.begin();
- }
- std::vector<int>::const_iterator SearchServer::begin() const
- {
- return document_ids_.begin();
- }
- std::vector<int>::iterator SearchServer::end()
- {
- return document_ids_.end();
- }
- std::vector<int>::const_iterator SearchServer::end() const
- {
- return document_ids_.end();
- }
- const map<string, double>& SearchServer::GetWordFrequencies(int document_id) const {
- static const std::map<std::string, double> dummy;
- if (document_to_word_freqs_.find(document_id) != document_to_word_freqs_.end()) {
- return document_to_word_freqs_.at(document_id);
- }
- return dummy;
- }
- void SearchServer::RemoveDocument(int document_id)
- {
- if (documents_.count(document_id) <= 0) return;
- documents_.erase(document_id);
- for (auto& word_freqs : word_to_document_freqs_)
- {
- word_freqs.second.erase(document_id);
- }
- document_to_word_freqs_.erase(document_id);
- document_ids_.erase(std::remove(document_ids_.begin(), document_ids_.end(), document_id), document_ids_.end());
- }
- void SearchServer::RemoveDocument(std::execution::sequenced_policy policy, int document_id){
- RemoveDocument(document_id);
- }
- void SearchServer::RemoveDocument(std::execution::parallel_policy policy, int document_id){
- vector<const string*> temp;
- transform(policy, word_to_document_freqs_.begin(), word_to_document_freqs_.end(), temp.begin(),
- [document_id](const auto& element){
- if(element.second.first == document_id){
- return element.first;
- }
- });
- document_to_word_freqs_.erase(document_id);
- document_ids_.erase(std::remove(document_ids_.begin(), document_ids_.end(), document_id), document_ids_.end());
- }
- SearchServer::SearchServer(const std::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 ((document_id < 0) || (documents_.count(document_id) > 0))
- {
- throw invalid_argument("Invalid document_id"s);
- }
- const auto words = SplitIntoWordsNoStop(document);
- const double inv_word_count = 1.0 / words.size();
- for (const string& word : words)
- {
- word_to_document_freqs_[word][document_id] += inv_word_count;
- document_to_word_freqs_[document_id][word] += inv_word_count;
- }
- documents_.emplace(document_id, DocumentData{ ComputeAverageRating(ratings), status});
- document_ids_.push_back(document_id);
- }
- vector<Document> SearchServer::FindTopDocuments(const 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 string& raw_query) const
- {
- return FindTopDocuments(raw_query, DocumentStatus::ACTUAL);
- }
- int SearchServer::GetDocumentCount() const
- {
- return static_cast<int>(documents_.size());
- }
- tuple<vector<string>, DocumentStatus> SearchServer::MatchDocument(const string& raw_query, int document_id) const
- {
- const auto 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 };
- }
- bool SearchServer::IsValidWord(const std::string& word)
- {
- // A valid word must not contain special characters
- return none_of(word.begin(), word.end(), [](char c)
- { return c >= '\0' && c < ' '; });
- }
- 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 (!IsValidWord(word))
- {
- throw invalid_argument("Word "s + word + " is invalid"s);
- }
- if (!IsStopWord(word))
- {
- words.push_back(word);
- }
- }
- return words;
- }
- int SearchServer::ComputeAverageRating(const std::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(const string& text) const
- {
- if (text.empty())
- {
- throw invalid_argument("Query word is empty"s);
- }
- string word = text;
- bool is_minus = false;
- if (word[0] == '-')
- {
- is_minus = true;
- word = word.substr(1);
- }
- if (word.empty() || word[0] == '-' || !IsValidWord(word))
- {
- throw invalid_argument("Query word "s + text + " is invalid");
- }
- return { word, is_minus, IsStopWord(word) };
- }
- SearchServer::Query SearchServer::ParseQuery(const string& text) const
- {
- Query result;
- for (const string& word : SplitIntoWords(text))
- {
- const auto query_word = ParseQueryWord(word);
- if (!query_word.is_stop)
- {
- if (query_word.is_minus)
- {
- result.minus_words.insert(query_word.data);
- }
- else
- {
- result.plus_words.insert(query_word.data);
- }
- }
- }
- return result;
- }
- double SearchServer::ComputeWordInverseDocumentFreq(const string& word) const
- {
- return log(GetDocumentCount() * 1.0 / word_to_document_freqs_.at(word).size());
- }
Advertisement
Add Comment
Please, Sign In to add comment