C++遍历std::vector查找最小值及对应索引结果异常排查
std::vector查找最小值索引结果异常问题修复
问题原因
错误出在循环内更新最小值索引的这行代码:
index = i ? (test[i] < test[index]) : index;
这行逻辑完全不符合预期:
- 当
i为0时,保持index为初始值0,这部分逻辑没有问题 - 当
i不为0时,代码直接将test[i] < test[index]的布尔比较结果赋值给了size_t类型的index:布尔值true会隐式转换为无符号整数1,false会隐式转换为0。
原本预期逻辑是「如果当前元素比已记录的最小值更小,就把当前下标i设为新的最小值索引」,但实际代码根本没有在比较成立时把i赋值给index,只会给index赋0或1两个值。
执行过程中刚好i=1时元素4.0小于初始最小值5.5,比较结果为true,index被赋值为1;后续i=2、i=3时哪怕元素更小,比较结果为true时给index赋的值还是1,永远不会更新为2、3,最终输出结果自然是错误的1。
修复方法
写法1:直观条件判断(推荐,可读性最高)
放弃错误的三目运算写法,直接用if判断更新索引即可,另外不要硬编码循环长度,直接取容器的size()更稳妥:
size_t index{0}; for (size_t i{0}; i < test.size(); ++i) { if (test[i] < test[index]) { index = i; } }
写法2:修正后的三目运算
如果习惯用三目运算符,要把返回值改成符合逻辑的i和原有index:
index = (i != 0 && test[i] < test[index]) ? i : index;
写法3:直接调用标准库实现(最稳妥,避免手写逻辑错误)
引入的<algorithm>头文件已经提供了std::min_element方法,可以直接定位范围内的最小值迭代器,计算迭代器偏移就能得到索引,不用手写循环:
auto min_it = std::min_element(test.begin(), test.end()); size_t min_index = std::distance(test.begin(), min_it); float min_value = *min_it;
内容的提问来源于stack exchange,提问作者Sebastian Schubert
相关产品推荐
相关产品推荐

