题目

编写程序,演示标准算法 std::min_element、std::max_element 与 std::minmax_element 的极值检索。掌握算法返回的是对应极值元素的迭代器指针,而非直接返回值;通过 std::distance 计算极值在容器中的物理下标偏移;演示传入自定义比较谓词,在复杂结构体列表(如气象站观测数据)中检索最高温度与最低气压记录。

输入格式:无需外部输入。

输出格式:输出极值元素数值、所在索引下标与结构体复杂多字段检索结果。

数据范围与约定:STL 极值迭代器、std::minmax 单次线性遍历 1.5N 次比对。

思路与算法

1. 单次遍历求双极值
若分别调用 min_element 和 max_element,需要遍历数组两次(共 \(2N\) 次比较);而调用 std::minmax_element 成对处理,仅需约 \(1.5N\) 次比较,显著提升缓存命中率。

2. 迭代器空容器防御
若传入空容器 v.empty(),max_element 会直接返回 v.end(),此时盲分解引用会导致未定义崩溃。必须防御 if (it != v.end())。

3. 自定义字段极值检索
配合 Lambda [](const Station& a, const Station& b){ return a.temp < b.temp; } 可在单行代码内完成任意结构体对象的极值筛选。

完整程序

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

struct WeatherRecord {
    std::string city;
    double temperature; // 摄氏度
    double pressure;    // 百帕
};

int main() {
    // 1. 基础数组极值检索
    std::vector<int> numbers = {14, 28, 56, 7, 91, 42, 7};

    // 使用 minmax_element 一次遍历同时获取最小与最大迭代器
    auto [minIt, maxIt] = std::minmax_element(numbers.begin(), numbers.end());

    int minIdx = std::distance(numbers.begin(), minIt);
    int maxIdx = std::distance(numbers.begin(), maxIt);

    std::cout << "--- 1. 数值数组双极值检索 ---\n";
    std::cout << "最小值: " << *minIt << " (首次出现下标: " << minIdx << ")\n";
    std::cout << "最大值: " << *maxIt << " (首次出现下标: " << maxIdx << ")\n\n";

    // 2. 自定义结构体极值检索
    std::vector<WeatherRecord> reports = {
        {"Beijing", 18.5, 1013.2},
        {"Harbin", -5.2, 1025.0},
        {"Haikou", 32.8, 1005.4},
        {"Lhasa", 12.0, 650.0}
    };

    // 寻找最高温度城市
    auto highestTempIt = std::max_element(reports.begin(), reports.end(),
        [](const WeatherRecord& a, const WeatherRecord& b) {
            return a.temperature < b.temperature;
        });

    // 寻找最低气压城市
    auto lowestPressureIt = std::min_element(reports.begin(), reports.end(),
        [](const WeatherRecord& a, const WeatherRecord& b) {
            return a.pressure < b.pressure;
        });

    std::cout << "--- 2. 气象观测站极值检测 ---\n";
    std::cout << "最高温度城市: " << highestTempIt->city 
              << " (" << highestTempIt->temperature << " °C)\n";
    std::cout << "最低气压城市: " << lowestPressureIt->city 
              << " (" << lowestPressureIt->pressure << " hPa)\n";

    return 0;
}

运行示例

输出:

--- 1. 数值数组双极值检索 ---
最小值: 7 (首次出现下标: 3)
最大值: 91 (首次出现下标: 4)

--- 2. 气象观测站极值检测 ---
最高温度城市: Haikou (32.8 °C)
最低气压城市: Lhasa (650 hPa)