确定对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;
有更好的方法吗?
答案 0 :(得分:3)
除非您从“开始”到“结束”遍历结构,否则您无法知道它是否已经排序,因此您可以做到最好的是O(n)。
我会选择第一个选择,即已经输入的选项。
答案 1 :(得分:3)
我认为你不能比O(n)更好地检查数组是否以与它开始的顺序不同的顺序返回。如果订单不能保证有效,那就劫持比较器以查看事情是否已经结束,因为从理论上讲,sort函数可以做任何它喜欢的比较,而不必移动任何东西。此外,跟踪是否执行了交换并不一定会告诉您订单是否发生了变化,因为排序也可以移动并在排序结束时将它们恢复到相同的顺序(例如,想想heapsort)。 p>
答案 2 :(得分:1)
如果交换了两个相等的值,您是否考虑修改范围?在这种情况下,already_sorted变体将无效。
否则它应该是最快的方式。
答案 3 :(得分:1)
如果要排序的对象是类类型,则可以引入一个operator =
重载的子对象,该对象将由std::swap
调用。但是,如果对象被交换然后交换回来,理论上仍然可以允许误报。
可能你应该坚持already_sorted
,直到你确定它占用了大量的总执行时间。