确定std :: sort(开始,结束)是否修改了范围

时间:2011-02-06 22:06:03

标签: c++ sorting stl std

确定对std::sort(begin, end)的调用是否实际修改了范围的最优雅方法是什么?

以下是我的两个想法:

(a)检查是否已经排序O(n):

if (already_sorted(begin, end)) { return false; }
std::sort(begin, end);
return true;

(b)跟踪比较器的变化(这样安全吗?):

bool modified = false;
std::sort(begin, end, [&modified](T a, T b){ modified |= a<b; return a<b; });
return modified;

有更好的方法吗?

4 个答案:

答案 0 :(得分:3)

除非您从“开始”到“结束”遍历结构,否则您无法知道它是否已经排序,因此您可以做到最好的是O(n)。

我会选择第一个选择,即已经输入的选项。

答案 1 :(得分:3)

我认为你不能比O(n)更好地检查数组是否以与它开始的顺序不同的顺序返回。如果订单不能保证有效,那就劫持比较器以查看事情是否已经结束,因为从理论上讲,sort函数可以做任何它喜欢的比较,而不必移动任何东西。此外,跟踪是否执行了交换并不一定会告诉您订单是否发生了变化,因为排序也可以移动并在排序结束时将它们恢复到相同的顺序(例如,想想heapsort)。 p>

答案 2 :(得分:1)

如果交换了两个相等的值,您是否考虑修改范围?在这种情况下,already_sorted变体将无效。

否则它应该是最快的方式。

答案 3 :(得分:1)

如果要排序的对象是类类型,则可以引入一个operator =重载的子对象,该对象将由std::swap调用。但是,如果对象被交换然后交换回来,理论上仍然可以允许误报。

可能你应该坚持already_sorted,直到你确定它占用了大量的总执行时间。