如何使用 STL 算法找到最小值和最大值?
How to find min and max using STL algorithms?
我有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
您可以定义以下类,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
地图中的每个元素。您可以使用与restaurant
映射大小相同的Rating
s 向量,并使用(从零开始(餐厅的 id 为向量中的元素编制索引:
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
我想向您展示一种可能的解决方案。有很多。。。
我的猜测是老师请求了 2 个单独的容器,因为他可能想稍后解释数据库,其中我们有一个主键"id"的父表"Student"和一个带有外键"id"(不是 NULL(的相关子表"Score"。
好的,那么让我们采用这种方法。我们创建 2 个类:"学生"和"分数"。我们构建它的载体。然后我们有一个带有属性的表(向量(。类成员是表的属性。这些表使用一些测试值进行初始化。
为了显示所有学生的所有计算值,我们使用基于for循环的范围遍历"students"表。然后,我们过滤"分数"表,以获取当前评估的学生ID。这类似于带有子查询的数据库 where 子句。
无论如何。然后我们将有一个表格,仅包含该学生的分数。然后我们对 STL 容器使用标准算法,如 std::min_element、std::max_element 和 std::accumulate。std::accumulate
用于计算平均值。因此,值的总和除以值的数量。
对于算法,我们使用 lambda 来访问正确的元素。
#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 << "nStudentnID: " << 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 << "nStudentnID: " << 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;
}
希望这有助于更好地理解
您可以分别使用 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所指的元素,即它在上限上是排他性的。
- 查找矩阵C++中每一列和每一行的最小和最大元素
- 如何在数组中交换最小和最大的位置?
- 需要使用模板查找数组的第二个最小和最小值
- 使用 std::min_element、std::max_element 查找矢量中的最小和最大元素
- 为什么我不能使用最小和最大这两个词作为变量名称?
- 在运行时为随机分布类成员设置最小和最大边界?
- 如何使用气泡排序从最小到最大对 4 个数组进行排序? C++
- 如何拒绝 cin 中的字符输入并定义最小和最大整数值
- 类型 *阵列的最小或最大值的类功能 *
- C++ 100 万个变量名称的最小和最大变量名称长度是多少
- 想要以正弦曲线的形式在循环中连续将值从最小变为最大
- 数组内存地址总是按最小到最大的顺序排列吗
- 使用向量而不是数组从最小到最大对数字进行排序C++
- 在 c++ 中给出两个整数向量(大小和类型相同),我想从最小到最大元素对一个进行排序,并更改第二个向量的顺序
- 在用户定义结构的向量中查找最小和最大元素的索引
- 二进制搜索,用于查找排序数组中比给定值最小和最大的元素
- c++中的函数如何以最小的复制返回值或引用?
- 我如何确定我可以传递给编译器选项的最小和最大值
- 如何为每个光栅带设置最小和最大颜色值(使用GDAL)
- 在c++中最小化分支-如果值是非零则递增