Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "search_server.h"
- #include <iterator>
- #include <chrono>
- #include <thread>
- using namespace std;
- void AddDocument(SearchServer& server, int document_id, const std::string_view document, DocumentStatus status,
- const std::vector<int>& ratings){
- server.AddDocument(document_id,document,status,ratings);
- }
- // void AddDocument(SearchServer& server, int document_id, const std::string& document, DocumentStatus status,const std::vector<int>& ratings){
- // AddDocument(server, document_id, std::string_view(document), status, ratings);
- // }
- void SearchServer::AddDocument(int document_id, string_view document, DocumentStatus status,
- const vector<int>& ratings) {
- if(document.empty())
- return;
- if ((document_id < 0) || (documents_.count(document_id) > 0)) {
- throw invalid_argument("Invalid document_id");
- }
- data_strings.emplace_back(document);
- const auto words = SplitIntoWordsNoStop(data_strings.back());
- const double inv_word_count = 1.0 / words.size();
- for (string_view 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_.insert(document_id);
- }
- vector<Document> SearchServer::FindTopDocuments(string_view 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(string_view raw_query) const {
- return FindTopDocuments(raw_query, DocumentStatus::ACTUAL);
- }
- const std::map<std::string_view, double>& SearchServer::GetWordFrequencies(int document_id) const{
- if (document_to_word_freqs_.count(document_id) != 0)
- return document_to_word_freqs_.at(document_id); //возможно использование только .at(), т.к. const
- else{
- static std::map<std::string_view, double> empty;
- return empty; //возвращает пустой map (см. инициализацию в конструкторе)
- //в противном случае было бы 1. Warning; 2. Невозможность передачи локальной переменной за пределы обл. видимости
- }
- }
- void SearchServer::RemoveDocument(int document_id){
- if (document_to_word_freqs_.count(document_id) != 0){
- for (auto& [word,doc]:document_to_word_freqs_.at(document_id))
- word_to_document_freqs_.at(word).erase(document_id);
- document_to_word_freqs_.erase(document_id); //удаление из map<int,map<string,double>>
- documents_.erase(document_id); //удаление из map<int,DocumentData>
- document_ids_.erase(document_id); //удаление из set<int>
- }
- }
- void SearchServer::RemoveDocument(std::execution::sequenced_policy t_exec, int document_id){
- RemoveDocument(document_id);
- }
- void SearchServer::RemoveDocument(std::execution::parallel_policy t_exec, int document_id){
- if (document_to_word_freqs_.count(document_id) != 0){
- std::vector<string_view> to_delete(document_to_word_freqs_.at(document_id).size());
- // std::transform(to_delete.begin(),to_delete.end(),to_delete.begin(),[](const auto word)->const string&{
- // return string(word.first);
- // });
- std::transform(document_to_word_freqs_[document_id].begin(),document_to_word_freqs_[document_id].end(),to_delete.begin(),[](const auto& word){
- return word.first;
- });
- std::for_each(t_exec,to_delete.begin(),to_delete.end(),[&](string_view word){
- word_to_document_freqs_[word].erase(document_id);
- });
- document_to_word_freqs_.erase(document_id); //удаление из map<int,map<string,double>>
- documents_.erase(document_id); //удаление из map<int,DocumentData>
- document_ids_.erase(document_id); //удаление из set<int>
- }
- }
- tuple<vector<string_view>, DocumentStatus> SearchServer::MatchDocument(string_view raw_query,
- int document_id) const {
- if(!document_ids_.count(document_id))
- throw out_of_range("Document don't exists");
- const auto query = std::move(ParseQuery(raw_query));
- std::vector<string_view> matched_words;
- if (std::any_of(query.minus_words.begin(),query.minus_words.end(),[this,&document_id](string_view word){
- if (!word_to_document_freqs_.count(word)==0)
- if (word_to_document_freqs_.at(word).count(document_id))
- return true;
- else return false;
- else return false;
- })){
- return {matched_words, documents_.at(document_id).status};
- }
- matched_words.reserve(query.plus_words.size());
- std::for_each(execution::seq,query.plus_words.begin(),query.plus_words.end(),[this,&document_id,&matched_words](string_view word){
- if (word_to_document_freqs_.count(word) == 0) {
- return;
- }
- else{
- if(word_to_document_freqs_.at(word).count(document_id))
- return matched_words.push_back(word);
- else
- return;
- }
- });
- //matched_words.resize(distance(matched_words.begin(),it));
- return {matched_words, documents_.at(document_id).status};
- }
- tuple<vector<string_view>, DocumentStatus> SearchServer::MatchDocument(execution::sequenced_policy,string_view raw_query,
- int document_id) const {
- return MatchDocument(raw_query,document_id);
- }
- tuple<vector<string_view>, DocumentStatus> SearchServer::MatchDocument(std::execution::parallel_policy,string_view raw_query,
- int document_id) const {
- if(!document_ids_.count(document_id))
- throw out_of_range("Document don't exists");
- const auto query = std::move(ParseQuery(execution::par,raw_query));
- std::vector<string_view> matched_words;
- if (std::any_of(execution::par,query.minus_words.begin(),query.minus_words.end(),[this,&document_id](string_view word){
- if (!word_to_document_freqs_.count(std::move(word.substr(1)))==0)
- if (word_to_document_freqs_.at(std::move(word.substr(1))).count(document_id))
- return true;
- else return false;
- else return false;
- })){
- return {matched_words, documents_.at(document_id).status};
- }
- matched_words.resize(query.plus_words.size());
- auto it = std::copy_if(execution::par,query.plus_words.begin(),query.plus_words.end(),matched_words.begin(),[this,&document_id](string_view word){
- if (word_to_document_freqs_.count(word) == 0) {
- return false;
- }
- else{
- if(word_to_document_freqs_.at(word).count(document_id))
- return true;
- else
- return false;
- }
- });
- sort(matched_words.begin(),it);
- matched_words.erase(unique(matched_words.begin(),it),matched_words.end());
- //matched_words.resize(distance(matched_words.begin(),it));
- return {matched_words, documents_.at(document_id).status};
- }
- SearchServer::Query<std::vector<std::string_view>> SearchServer::ParseQuery(string_view text) const {
- Query<std::vector<std::string_view>> result;
- const auto string_query = SplitIntoWords(text);
- result.minus_words.reserve(string_query.size());
- result.plus_words.reserve(string_query.size());
- std::for_each (string_query.begin(),string_query.end(),[&result,this](string_view word){
- const auto query_word = std::move(ParseQueryWord(word));
- if (!query_word.is_stop) {
- if (query_word.is_minus) {
- result.minus_words.push_back(std::move(query_word.data));
- }
- else {
- result.plus_words.push_back(std::move(query_word.data));
- }
- }
- });
- sort(result.minus_words.begin(),result.minus_words.end());
- result.minus_words.erase(unique(execution::seq,result.minus_words.begin(),result.minus_words.end()),result.minus_words.end());
- sort(result.plus_words.begin(),result.plus_words.end());
- result.plus_words.erase(unique(execution::seq,result.plus_words.begin(),result.plus_words.end()),result.plus_words.end());
- return result;
- }
- SearchServer::Query<std::vector<std::string_view>> SearchServer::ParseQuery(std::execution::sequenced_policy, string_view text) const {
- return ParseQuery(text);
- }
- SearchServer::Query<std::vector<std::string_view>> SearchServer::ParseQuery(std::execution::parallel_policy, string_view text) const {
- Query<std::vector<std::string_view>> result;
- const auto string_query = std::move(SplitIntoWords(text));
- result.plus_words.resize(string_query.size());
- auto it_plus = std::copy_if(execution::par,string_query.begin(),string_query.end(),result.plus_words.begin(),[&](string_view word){
- const auto query_word = std::move(ParseQueryWord(word));
- return (!query_word.data.empty() && !query_word.is_stop && !query_word.is_minus)?true:false;});
- result.plus_words.erase(it_plus,result.plus_words.end());
- result.minus_words.resize(string_query.size());
- auto it_minus = std::copy_if(execution::par,string_query.begin(),string_query.end(),result.minus_words.begin(),[this](string_view word){
- const auto query_word = std::move(ParseQueryWord(word));
- if ((!query_word.data.empty() && !query_word.is_stop && query_word.is_minus)){
- return true;
- }
- else return false;
- });
- result.minus_words.erase(it_minus,result.minus_words.end());
- return result;
- }
- std::vector<std::string_view> SearchServer::SplitIntoWordsNoStop(const std::string_view text) const {
- std::vector<std::string_view> words;
- std::vector<std::string_view> temp=std::move(SplitIntoWords(text));
- words.reserve(temp.size());
- using namespace std::string_literals;
- for (const std::string_view word : temp) {
- if (!IsValidWord(word)) {
- throw std::invalid_argument("Word "s + word.data() + " 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 = 0;
- for (const int rating : ratings) {
- rating_sum += rating;
- }
- return rating_sum / static_cast<int>(ratings.size());
- }
- SearchServer::QueryWord SearchServer::ParseQueryWord(const std::string_view text) const {
- if (text.empty()) {
- throw std::invalid_argument("Query word is empty"s);
- }
- std::string_view word;
- bool is_minus = false;
- if (text[0] == '-') {
- is_minus = true;
- word = text.substr(1);
- }
- else
- word = text;
- if (word.empty() || word[0] == '-' || !IsValidWord(word)) {
- throw std::invalid_argument("Query word "s + string(text) + " is invalid"s);
- }
- return {word, is_minus, IsStopWord(word)};
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement