stable_sort不保持元素的顺序

时间:2017-05-25 20:44:38

标签: c++

我有一个Object的std :: vector,Object可以是Empty或NotEmpty(这是一个内部状态,Object本身总是有效的。)

我想按内部状态对矢量进行排序,同时保持排序前的相对顺序。

理论上(除非我遗漏了什么)我只需要检查比较函数的第一个元素的内部状态:

    // i want to keep the NonEmptys first
    std::stable_sort(vec.begin(), vec.end(), [](const auto& first, const auto& second)
    {
        return first.getStatus() != Status::Empty;
    });

事情是,这与排序前的顺序不一致,事实上,如果我再次排序,它只会颠倒NonEmptys的顺序。

我读到了严格的弱排序,并尝试了几个比较函数总是具有相同的结果(甚至尝试过如果两个Empty都返回false)。

提前致谢。

2 个答案:

答案 0 :(得分:4)

传递给std::stable_sort的比较器不会形成有效的排序。例如,如果我们将object1object2都设为空,那么object1 < object2 object2 < object1(使用比较器)。这与标准排序功能不相符。

你真正想要的是std::stable_partition

std::stable_partition(vec.begin(), vec.end(), [](const auto& object)
{
    return object.getStatus() != Status::Empty;
});

答案 1 :(得分:2)

来自std::stable_sort

  

<强>参数

     

comp - 比较函数对象(即满足Compare要求的对象),如果第一个参数小于(即在之前排序)第二个参数,则返回true。

这意味着,为了对非空的第一个进行排序,如果first非空且second为空,则比较函数必须返回true。反过来说,它必须返回false。如果两者都为空或两者都非空,则它也必须返回false,因为first不小于second

因此比较函数减少到

[](const auto &first, const auto &second) {
    return first.getStatus() != Status::Empty && second.getStatus() == Status.Empty;
}

现在,std::stable_sort知道哪个元素更少,同样重要的是哪些元素等效