首页 > 解决方案 > 如何使用 STL 算法找到最小值和最大值?

问题描述

我有resturentratings。如何使用 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

标签: c++dictionarystl

解决方案


我想向您展示一种可能的解决方案。有许多 。. .

我的猜测是老师要求 2 个单独的容器,因为他可能想稍后解释数据库,其中我们有一个带有主键“id”的父表“Student”和一个带有外键“id”的相关子表“Score” "(非空)。

好的,那我们就采用这种方法。我们创建了 2 个类:“学生”和“分数”。我们构建它的向量。然后我们有一个带有属性的表(向量)。类成员是表的属性。这些表使用一些测试值进行初始化。

为了显示所有学生的所有计算值,我们使用基于范围的 for 循环遍历“学生”表。然后我们为当前评估的学生id过滤“分数”表。这类似于带有子查询的数据库 where 子句。

反正。然后我们将有一个表,其中仅包含该学生的分数。然后我们对 STL 容器使用标准算法,例如std::min_elementstd::max_elementstd::accumulatestd::accumulate用于计算平均值。因此,值的总和除以值的数量。

对于算法,我们使用 lambdas 来访问正确的元素。

#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;
}

由于编写 lambda 的工作有些乏味,我们做了一个小改进,并重载了 Score 类的“<”和“+”运算符。这样就不需要 lambda,std::algorithms 将直接使用类中的运算符。

请参见:

#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;
}

希望这有助于更好地理解


推荐阅读