c++ - std::is_sorted 的奇怪行为

标签 c++ algorithm sorting compare assert

我正在学习 C++ 中的断言,我遇到了 std::is_sorted 的奇怪行为。

给定一个比较器 (c) 和未排序的 std::strings vector (v)。我使用 std::sort(v.begin(),v.end(),comparator)。然后用相同的参数调用 std::is_sorted。结果是假的,为什么会这样?

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
#include <cassert>
int main(){
    auto comparator([](std::string a , std::string b) {return a.length() - b.length();} );
    std::vector<std::string> v {"y" , "yyyy" , "yy" ,
                                 "yy" , "yyyyyyy" , "yyy"};
    assert(false == std::is_sorted(v.begin() , v.end(),comparator));
    std::sort(v.begin(), v.end(),comparator);
    assert(true == std::is_sorted(v.begin() , v.end(),comparator));
}

最佳答案

您的谓词无法正常工作。如果你打算按字符串长度排序,你需要

auto comparator([](std::string a , std::string b) {return a.length() < b.length();} );

你贴出的原始谓词返回字符串长度差,是整数类型,在被std::sort调用时可以转化为bool,并做result对于不同于 0 的所有内容,在 true 中,否则为 false。因此,每个不相等的字符串长度都会导致谓词被评估为 true,并且由于谓词始终为“true”,具有不同字符串长度的序列元素将被无限交换。这会导致未定义的行为。

这里的术语是谓词必须实现“严格的弱排序”,例如记录在案在 cppreference .感谢@FrançoisAndrieux 和@Peter 在这方面的评论。

还可以考虑通过 const std::string&std::string_view 传递参数以避免不必要的复制。

关于c++ - std::is_sorted 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56687913/

相关文章:

c++ - 有没有一种编程方式来估计我的 CPU 执行 fp 操作所花费的时间?

c++ - gtkmm 中的程序不会显示按钮

r - 由于 kd-tree 最近邻搜索中的最大半径导致意外减速

c++ - 在 C++ 中对对象的输入数组进行排序

linux 在列内排序

C++ 结束这个 8 位 for 循环的最佳方法是什么

c++ - 比较两个 DRIVER_OBJECT 是否相等?

java - Java 中的字符数组迭代 - 改进算法

c++ - 使用 CUDA 并行特征值求解器

Java Sorting : sort an array of objects by property, 对象不允许使用 Comparable