C ++排序迭代有时会给出错误的值

时间:2016-11-07 08:39:28

标签: c++

tour_indexes.clear();
for (int i=0; i<num_of_cities; i++)
{
    tour_indexes.push_back(i);
}

mt19937 gen(random_engine());
uniform_real_distribution<> dis(0, 1);

// Sort indexes based on comparing values in tour. Choose at random if equal
sort(tour_indexes.begin(), tour_indexes.end(),
     [&tour, &dis, &gen](int &i1, int &i2)
{
    if (tour[i1] == tour[i2])
    {
        return dis(gen) < 0.5;
    }
    return tour[i1] < tour[i2];
});

这给了我tour[i1] == tour[i2]的段错误,在调试时我发现它是因为i2有时(看似不确定)的方式比它应该更大。当tour_indexes为f.ex 0 - 20时(见{0}} tour_indexes不包含i2的错误时间,我进行了双重检查)。{/ 403} >

这一切都发生在包含成员变量tour_indexes的类中的成员函数中。如果相关,则类对象位于shared_ptr中。任何想法可能是什么问题?感谢。

2 个答案:

答案 0 :(得分:4)

您的比较器未提供严格的弱排序。具体来说,如果tour[i1] == tour[i2]有50/50的可能性,它将返回true或false 并且答案不稳定(必须是)。

如果您的比较函数没有提供严格的弱排序,则行为是未定义的,并且seg-fault是一种似是而非的行为。

我建议使用return i1 < i2;这将以稳定的方式打破平局。

或者,根本不需要打破平局。只需使用

[&tour](int i1, int i2) 
{
    return tour[i1] < tour[i2]; 
}

std::sort排序非常满意;这意味着cmp(i1,i2)cmp(i2,i1)都可能返回false。它无法应对的是它们都返回true(或两个使用相同参数返回不同值的调用。)

答案 1 :(得分:1)

删除比较运算符中的随机化。或许algortihm失败是因为i1&lt; i2和i2&lt;如果元素相等,则i1可以为真。

如果相等的元素和stable_sort给出数组中相等元素的确定性顺序,则

sort已经给出了一个随机顺序。