Вопрос:

Как найти минимальное и максимальное с использованием алгоритмов STL?

c++ dictionary stl

87 просмотра

3 ответа

16 Репутация автора

У меня есть resturentи ratings. Как я могу использовать контейнеры STL, чтобы найти минимальное и максимальное значения рейтинга ресторана? Нужно ли использовать алгоритм STL максимального и минимального рейтинга? Я должен буду найти средний рейтинг, используя любые методы.

Id  Name
1   McDonalds 
2   Wendys 
3   Burger King

Id  Resturent Rating
1     100
2     90
3     85
1     80
2     90
3     100
1     85
2     75
3     100




int main {

  map<int, string> resturent;

  stu.insert(pair<int, string>(1,  "McDonalds")));
  stu.insert(pair<int, string>(2, "Wendys")));
  stu.insert(pair<int, string>(3,"Burger King")));

  multimap<int, int> rating;
  testScore.insert(pair<int, int>(1, 10));
  testScore.insert(pair<int, int>(2, 9));
  testScore.insert(pair<int, int>(3, 8));
  testScore.insert(pair<int, int>(1, 8));
  testScore.insert(pair<int, int>(2, 6));
  testScore.insert(pair<int, int>(3, 10));
  testScore.insert(pair<int, int>(1, 5));
  testScore.insert(pair<int, int>(2, 7));
  testScore.insert(pair<int, int>(3, 9));
}

Ожидаемый ответ:

Resturent:McDonalds Id:1
Max Rating: 10
Min Rating: 5
Average Rating:7.67
Автор: salman khan Источник Размещён: 10.08.2019 02:10

Ответы (3)


1 плюс

1594 Репутация автора

Я хотел бы показать вам одно возможное решение. Здесь очень много . , ,

Я предполагаю, что учитель запросил 2 отдельных контейнера, потому что он может захотеть объяснить базы данных позже, где у нас есть родительская таблица «Student» с первичным ключом «id» и связанная дочерняя таблица «Score» с внешним ключом «id». " (ненулевой).

Хорошо, тогда давайте использовать этот подход. Мы создаем 2 класса: «Студент» и «Счёт». Мы строим векторы этого. Тогда у нас есть таблица (вектор) с атрибутами. Члены класса являются атрибутами таблицы. Таблицы инициализируются с некоторыми тестовыми значениями.

Чтобы показать все рассчитанные значения для всех студентов, мы перебираем таблицу «студентов» с диапазоном, основанным на цикле. Затем мы фильтруем таблицу «баллов» для текущего оцененного идентификатора студента . Это похоже на базу данных, где предложение с подзапросом.

Тем не мение. Тогда у нас будет таблица, содержащая только оценки для этого студента. Затем мы используем стандартные алгоритмы для контейнеров STL, такие как std :: min_element , std :: max_element и std :: аккумулировать . std::accumulateИспользуются для расчета среднего значения . Итак, сумма значений делится на количество значений.

Для алгоритмов мы используем лямбды для доступа к правильным элементам.

#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <numeric>

struct Student
{
    unsigned int id{};
    std::string name{};

};
struct Score
{
    unsigned int id{};
    unsigned int score{};
};

std::vector<Student> students{ {1U,"John"},{2U,"Mary"},{3U,"Luke"},{4U,"Lisa"} };
std::vector<Score> scores{ {3U,100U},{4U,80U},{2U,90U},{1U,85U},{1U,95U},{2U,90U},{3U,80U},
                           {4U,95U},{3U,100U},{1U,80U},{2U,85U},{3U,95U},{1U,95U},{2U,100U},{3U,95U} };

int main()
{
    // Calculating all results
    for (const Student& student : students) {

        // Filter out the scores for this student
        std::vector<Score> scoreForThisStudent{};
        std::copy_if(scores.begin(), scores.end(), std::back_inserter(scoreForThisStudent), [&student](const Score & s) { return student.id == s.id; });

        // Check, if scores are available. Calculate only in this case
        if (scoreForThisStudent.size()) {
            std::cout << "\nStudent\nID: " << std::left << std::setw(4) << student.id << "    Name: " << student.name
                << "\nMin Score:        " << std::min_element(scoreForThisStudent.begin(), scoreForThisStudent.end(), [](const Score & s1, const Score & s2) {return s1.score < s2.score; })->score
                << "\nMax Score:        " << std::max_element(scoreForThisStudent.begin(), scoreForThisStudent.end(), [](const Score & s1, const Score & s2) {return s1.score < s2.score; })->score
                << "\nNumber of Scores: " << scoreForThisStudent.size()
                << "\nAverage:          " << std::accumulate(scoreForThisStudent.begin(), scoreForThisStudent.end(), 0U, [](const unsigned int s1, const Score & s2) {return s1 + s2.score; }) / scoreForThisStudent.size() << "\n";
        }
    }
    return 0;
}

В связи с несколько утомительной работой по написанию лямбд, мы делаем одно небольшое улучшение и перегружаем операторы «<» и «+» нашего класса Score. При этом нет необходимости в лямбдах, и алгоритмы std :: будут напрямую использовать операторы из класса.

Посмотри пожалуйста:

#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <numeric>

struct Student
{
    unsigned int id{};
    std::string name{};

};
struct Score
{
    unsigned int id{};
    unsigned int score{};
    bool operator < (const Score& other) const { return score < other.score; }
    friend unsigned int operator + (const unsigned int val, const Score& other) { return val + other.score; }
};

std::vector<Student> students{ {1U,"John"},{2U,"Mary"},{3U,"Luke"},{4U,"Lisa"} };
std::vector<Score> scores{ {3U,100U},{4U,80U},{2U,90U},{1U,85U},{1U,95U},{2U,90U},{3U,80U},
                           {4U,95U},{3U,100U},{1U,80U},{2U,85U},{3U,95U},{1U,95U},{2U,100U},{3U,95U} };

int main()
{
    // Calculating all results
    for (const Student& student : students) {

        // Filter out the scores for this student
        std::vector<Score> scoreForThisStudent{};
        std::copy_if(scores.begin(), scores.end(), std::back_inserter(scoreForThisStudent), [&student](const Score &s) { return student.id == s.id; });

        // Check, if scores are available. Calculate only in this case
        if (scoreForThisStudent.size()) {
            // Calculate all required values
            std::cout << "\nStudent\nID: " << std::left << std::setw(4) << student.id << "    Name: " << student.name
                << "\nMin Score:        " << std::min_element(scoreForThisStudent.begin(), scoreForThisStudent.end())->score
                << "\nMax Score:        " << std::max_element(scoreForThisStudent.begin(), scoreForThisStudent.end())->score
                << "\nNumber of Scores: " << scoreForThisStudent.size() 
                << "\nAverage:          " << std::accumulate(scoreForThisStudent.begin(), scoreForThisStudent.end(), 0U) / scoreForThisStudent.size() << "\n";
        }
    }
    return 0;
}

Надеюсь, это поможет лучше понять

Автор: Armin Montigny Размещён: 10.08.2019 07:48

0 плюса

368 Репутация автора

Вы можете использовать min_element (start_iterator, end_iterator) и max_element (start_iterator, end_iterator) соответственно, что возвращает итератор к наибольшему значению в диапазоне. Ну вот!!!

#include <iostream>     
#include <algorithm>    

using namespace std;

int main () {
  int myints[] = {3,7,2,5,6,4,9};

  //Method 1
  int minElement = *min_element(myints, myints+7);
  int maxElement = *max_element(myints, myints+7);      
  cout<<"Max: "<< maxElement <<"\n";
  cout<<"Min: "<< minElement <<"\n";


  // Method 2: added by @HolyBlackCat
  int result = minmax_element(myints, myints+7);   //return a pair with iterator pointing to minimum element
  cout<<"Max: "<< *result.first <<"\n";
  cout<<"Min: "<< *result.second <<"\n";


  // Method 3:
  int result = minmax(myints, myints+7);   //return a pair of min,max element
  cout<<"Max: "<< result.first <<"\n";
  cout<<"Min: "<< result.second <<"\n";


  return 0;
}

PS: элемент, на который указывает last_iterator, не включен. то есть это исключительно на верхней границе.

Автор: Abhinav1602 Размещён: 10.08.2019 01:06

0 плюса

11579 Репутация автора

Вы можете определить следующий класс Ratingsдля получения статистики рейтингов ресторана:

#include <limits>

class Ratings {
   unsigned num_{0};  // number of ratings inserted
   long long sum_{0}; // sum of all the inserted ratings
   int min_{std::numeric_limits<int>::max()};
   int max_{std::numeric_limits<int>::min()};

public:
   void insert_rating(int rating) {
      // update minimum
      if (rating < min_)
         min_ = rating;

      // update maximum
      if (rating > max_)
         max_ = rating;

      // update sum
      sum_ += rating;

      // update number of ratings
      num_++;
   }

   double average() const {
      // calculate the average rating
      return (double)sum_ / num_; 
   }

   int min() const { return min_; }
   int max() const { return max_; }
};

Он отслеживает минимум, максимум, сумму и количество вставленных оценок. Поэтому получение минимума, максимума и среднего выполняется за постоянное время. Добавление рейтинга также делаются в постоянное время , так как он просто требует постоянного числа операций, то есть обновление min_, max_, sum_и num_.

Затем вам нужен Ratingобъект для каждого ресторана для оценки, то есть для каждого элемента на restaurantкарте. Вы можете иметь вектор Ratings такого же размера, что и restaurantкарта, и использовать идентификатор ресторана (с нуля) для индексации элементов в векторе:

int main() {
   // id to restaurant
   std::map<int, std::string> restaurant;

   restaurant.insert({0, "McDonalds"});
   restaurant.insert({1, "Wendys"});
   restaurant.insert({2, "Burger King"});

   // a Ratings object for each restaurant
   std::vector<Ratings> ratings(restaurant.size());

   ratings[0].insert_rating(10);
   ratings[1].insert_rating(9);
   ratings[2].insert_rating(8);
   ratings[0].insert_rating(8);
   ratings[1].insert_rating(6);
   ratings[2].insert_rating(10);
   ratings[0].insert_rating(5);
   ratings[1].insert_rating(7);
   ratings[2].insert_rating(9);

   for (int i = 0; i < ratings.size(); ++i) {
      std::cout << "Restaurant: " << restaurant[i] << ", Id: " << i << '\n';
      std::cout << "Max Rating: " << ratings[i].max() << '\n';
      std::cout << "Min Rating: " << ratings[i].min() << '\n';
      std::cout << "Average Rating: " << ratings[i].average() << '\n';
      std::cout << '\n';
   }
}

Выход этой программы:

Restaurant: McDonalds, Id: 0
Max Rating: 10
Min Rating: 5
Average Rating: 7.66667

Restaurant: Wendys, Id: 1
Max Rating: 9
Min Rating: 6
Average Rating: 7.33333

Restaurant: Burger King, Id: 2
Max Rating: 10
Min Rating: 8
Average Rating: 9
Автор: El Profesor Размещён: 11.08.2019 08:43
Вопросы из категории :
32x32