如何在不修改范围的情况下逆序遍历元素?代码问题求助
问题解答
问题回顾
想要在不修改输入数据的前提下按降序访问容器内元素,因此无法使用std::sort。尝试用std::max_element实现,但当max等于std::begin()时,无法找到当前最大值的下一个更小值,代码如下:
const std::vector<int> v{2, 1, 4, 5, 0, 6, 4, 3, 2}; auto max = std::max_element(v.begin(), v.end()); auto min = std::min_element(v.begin(), v.end()); auto tmp = std::begin(v); while(*max != *min) { tmp = std::max_element(v.begin(), v.end(), [max](const auto& item1, const auto& item2) { return item2 < *max && item1 < item2; }); max = tmp; }
错误原因
你给std::max_element编写的自定义比较函数逻辑完全错误。std::max_element的比较函数规则是:如果第一个参数应该被判定为“小于”第二个参数(即算法会优先保留第二个参数),则返回true。你的lambda返回item2 < *max && item1 < item2,既没有筛选出小于当前最大值的元素,也没有正确比较元素大小,自然无法定位到目标的“次大值”。
修正方案
核心思路是:每次在容器中找到小于当前最大值的所有元素里的最大值,直到遍历到最小值。正确的比较函数需要帮std::max_element筛选出符合条件的元素,并找出其中最大的那个。
修正后的代码示例:
#include <vector> #include <algorithm> #include <iostream> int main() { const std::vector<int> v{2, 1, 4, 5, 0, 6, 4, 3, 2}; auto current_max = std::max_element(v.begin(), v.end()); const auto min_it = std::min_element(v.begin(), v.end()); // 先输出全局最大值 std::cout << *current_max << " "; while (current_max != min_it) { // 查找小于当前最大值的最大元素 auto next_max = std::max_element(v.begin(), v.end(), [current_max](const int& a, const int& b) { bool a_valid = a < *current_max; bool b_valid = b < *current_max; if (!a_valid && b_valid) { // a不符合条件,b符合,优先选b return true; } if (a_valid && b_valid) { // 两者都符合,选更大的那个(a小于b则返回true,算法保留b) return a < b; } // 其他情况不替换当前候选 return false; }); current_max = next_max; std::cout << *current_max << " "; } std::cout << std::endl; return 0; }
额外说明:如果你的需求是遍历所有元素的降序(包括重复值),上述代码仅输出不同大小的元素,还需要调整逻辑(比如记录已访问的元素位置,每次找到符合大小条件且未被访问的元素)。但如果只是按“从大到小的不同数值”访问,上面的代码完全可行。
内容的提问来源于stack exchange,提问作者mr__orangee
相关产品推荐
相关产品推荐

