最近做题踩到了这种冷门的坑,在自定义sort排序的比较函数cmp的时候,因为没有完全遵守严格弱排序,导致程序的测评结果返回RUNTIME ERROR,这里学习了一下严格弱排序的知识。
在對容器進行std::sort算法排序時,算法所使用的仿函數或者普通函數必須保證符合嚴格若排序(strict weak order),否則,算法會報錯,從而終止程序。
引用wikipedia中的說明:
A strict weak ordering has the following properties. For all x and y in S,
- For all x, it is not the case that x < x (irreflexivity).(即在stl的算法函數中若兩個相同的容器對象做比較,返回false)
- For all x ≠ y, if x < y then it is not the case that y < x (asymmetric).
- For all x, y, and z, if x < y and y < z then x < z (transitivity).
- For all x, y, and z, if x is incomparable with y, and y is incomparable with z, then x is incomparable with z (transitivity of equivalence).
這裡的<可以是根據排序需求而變換的任意的關係,并不僅僅局限於“<”:比如在stl中使用的比較函數(仿函數)。
我们所使用的sort原型是这样:
template <class RandomAccessIterator, class Compare> void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
手册中对于第三个参数的说明是这样(http://www.cplusplus.com/reference/algorithm/sort/?kw=sort ):
comp Binary function that accepts two elements in the range as arguments, and returns a value convertible tobool. The value returned indicates whether the element passed as first argument is considered to go before the second in the specific strict weak ordering it defines. The function shall not modify any of its arguments. This can either be a function pointer or a function object.
(翻译:comp是一个接受两个表示范围的元素作为参数的二元函数,它返回一个可转成bool的值。返回值指示了在comp定义的特定的严格弱排序中,第一个参数是否应该排在第二个参数之前。comp函数不会改变任何一个参数,它可以是一个函数指针或一个仿函数。)
我们注意到该说明提到了comp参数必须是严格弱排序。网上的一个较好的解读是:严格是说在判断的时候会用"<",而不是"<=",弱排序是因为,一旦"<"成立便认为存在"<"关系,返回ture,而忽略了"="关系和">"区别,把它们归结为false。相关定义可以参阅:http://www.sgi.com/tech/stl/StrictWeakOrdering.html
https://msdn.microsoft.com/zh-cn/library/wh15hsex.aspx
简单说,在comp中,当参数1和参数2等价时,必须返回false.