询问C++中查找二维vector最大值的更简洁实现方式
询问C++中查找二维vector最大值的更简洁实现方式
作为从C#转过来的开发者,习惯了LINQ那种一行搞定的简洁写法,看到你现在的C实现肯定会觉得有点繁琐对吧?别担心,C其实也有不少更简洁的方式来实现二维vector找最大值的需求,我给你整理几种不同版本的方案,你可以根据自己能用的C++标准来选:
首先先说说你当前的代码:逻辑是完全没问题的——先收集每行的最大值到临时容器,再找这个容器的最大值,但确实可以省去中间的临时vector,优化内存和代码长度。
方案1:C++11及以上可用,用范围for直接跟踪最大值
这种写法不用额外的临时容器,直接遍历每行的时候更新当前最大值,代码更紧凑:
#include <algorithm> #include <climits> // 用来使用INT_MIN int max_value() { // 初始值设为int的最小值,避免所有元素都是负数时出错 int current_max = INT_MIN; // 用范围for遍历每一行,更直观 for (const auto& row : score) { // 找到当前行的最大值 auto row_max = *std::max_element(row.begin(), row.end()); // 更新全局最大值 current_max = std::max(current_max, row_max); } return current_max; }
方案2:C++17及以上可用,用std::reduce模拟LINQ的Aggregate
这个写法和你C#里的Aggregate思路几乎一致,用std::reduce来逐步累积最大值,代码更接近你熟悉的风格:
#include <algorithm> #include <numeric> // std::reduce需要的头文件 #include <climits> int max_value() { return std::reduce(score.begin(), score.end(), INT_MIN, [](int current_max, const std::vector<int>& row) { // 每次把当前最大值和行最大值比较,返回更大的那个 return std::max(current_max, *std::max_element(row.begin(), row.end())); }); }
方案3:C++20及以上可用,用范围库一行搞定
如果你能用到C++20的范围库,那这绝对是最简洁的写法,直接把二维vector展平成一维视图,然后找最大值,和LINQ的感觉一模一样:
#include <ranges> #include <algorithm> #include <climits> int max_value() { // 先判断容器是否为空,避免未定义行为 if (score.empty() || std::ranges::any_of(score, [](const auto& row) { return row.empty(); })) { throw std::invalid_argument("Score vector or its rows cannot be empty"); } // views::join把二维vector展平成一维视图(不需要复制元素),然后直接找最大值 return *std::ranges::max_element(score | std::views::join); }
额外注意点
不管用哪种方案,都要考虑空容器的情况——如果score是空的,或者某一行是空的,直接调用std::max_element会导致未定义行为,所以最好在代码开头加个空值检查,比如像方案3那样抛出异常,或者返回你业务逻辑里的默认值。
备注:内容来源于stack exchange,提问作者IntoNET
相关产品推荐
相关产品推荐

