简体   繁体   English

与三值比较函数相比,仅使用小于运算符进行排序

[英]Sorting only using the less-than operator compared to a trivalue compare function

In C++/STL sorting is done by using only the less-than operator. 在C ++ / STL中,仅使用less-than运算符进行排序。 Altough I have no idea how the sorting algorithms are actually implemented, I assume that the other operations are created implicite: 尽管我不知道排序算法是如何实际实现的,但我认为其他操作是隐含的:

a > b *equals* b < a == true
a == b *equals* !(a < b) && !(b < a)

Compared to using a trivalue* compare function, like for example Java, is this good for performance, or why was this design decision made? 与使用trivalue * compare函数(例如Java)相比,这对性能有好处,或者为什么要做出这样的设计决策呢?

My assumption is that any trivalue compareto function still has to implement these comparissons in itself, resulting in the same performance. 我的假设是,任何trivalue compareto函数仍然必须实现这些比较,从而产生相同的性能。

**by trivalue compare function, I mean a compare function which returns -1, 0 and 1 for less than, equal and higher than* **通过trivalue比较函数,我的意思是比较函数,它返回-1,0和1小于,等于和大于*

Update: It seems a spaceship <=> operator are coming in C++20 so obviously the committee thought there were downsides of using only operator< . 更新:似乎太空船<=>运营商正在使用C ++ 20,所以显然委员会认为仅使用operator<缺点。

In a sense the other two are implicit, but more accurate would be to say that a comparison sort doesn't actually need a tri-valued comparator, and C++'s sorts are implemented in a way which doesn't use one in order to minimise the behaviour required of the comparator. 从某种意义上说,另外两个是隐式的,但更准确的是说比较排序实际上并不需要三值比较器,并且C ++的排序是以不使用一个的方式实现的,以便最小化比较器所需的行为。

It would be wrong for std::sort to define and exclusively use something like this: std :: sort定义并专门使用这样的东西是错误的:

template <typename T, typename Cmp>
int get_tri_value(const T &a, const T &b, Cmp lessthan) {
    if (lessthan(a,b)) return -1;
    if (lessthan(b,a)) return 1;
    return 0;
}

... because you'd end up with an inefficient algorithm in terms of number of calls to lessthan . ......因为你最终在呼叫数量方面的低效算法lessthan If your algorithm doesn't do anything useful with the difference between a 1 return and a 0 return, then you've wasted a comparison. 如果你的算法没有对1返回和0返回之间的差异做任何有用的事情,那么你就浪费了一个比较。

C++ refers to "strict weak orderings". C ++指的是“严格的弱排序”。 If < is a strict weak ordering, and !(a < b) && !(b < a) , it doesn't necessarily follow that a == b . 如果<是严格的弱排序,并且!(a < b) && !(b < a) ,则不一定遵循a == b They're just "in the same place" in the ordering, and !(a < b) && !(b < a) is an equivalence relation. 它们在排序中只是“在同一个地方”,并且!(a < b) && !(b < a)是等价关系。 So the comparator required by sort orders equivalence classes of objects, it doesn't provide a total order. 因此,所要求的比较sort顺序等价 ,它并没有提供一个总订单。

The only difference it makes is what you say when !(a < b) . 唯一的区别就是你说的时候!(a < b) For a strict total order, you would deduce b <= a , read "less than or equal to". 对于严格的总订单,您将推导出b <= a ,读取“小于或等于”。 For a strict weak order, you can't define b <= a to mean b < a || b == a 对于严格的弱序,您不能将b <= a定义为b < a || b == a b < a || b == a and have this be true. b < a || b == a并且这是真的。 C++ is pedantic about this, and since it allows operator overloading it pretty much has to be, since people overloading operators need the jargon in order to tell users of their code what they can expect in terms of how the operators relate. C ++对此很迂腐,因为它允许运算符重载它几乎必须如此,因为人们重载运算符需要术语,以便告诉用户他们的代码在运算符如何关联方面可以期待什么。 Java does talk about the comparator and the hashCode being consistent with equals, which is all you need. Java确实讨论了比较器和hashCode与equals一致,这就是你所需要的。 C++ has to deal with <, >, ==, <=, >=, the post-condition of assignment, and so on. C ++必须处理<,>,==,<=,> =,赋值的后置条件,等等。

C++ takes quite a pure mathematical approach to this in the API, so everything is defined in terms of the single binary relation. C ++在API中采用了相当纯粹的数学方法,因此所有内容都是根据单个二元关系定义的。 Java is friendlier in some respects, and prefers three-way comparisons where the definition of the fundamental unit (the comparison) is a bit more complex, but the logic leading from it is simpler. Java在某些方面更友好,并且更喜欢三向比较,其中基本单元的定义(比较)稍微复杂一些,但是由它引出的逻辑更简单。 It also means the sort algorithm gets more information per comparison, which occasionally is useful. 这也意味着排序算法在每次比较时获得更多信息,这有时是有用的。 For an example, see the "Dutch flag" quicksort optimisation, which is a benefit when there are a lot of "in the same place" duplicates in the data. 例如,请参阅“荷兰旗”快速排序优化,这在数据中存在大量“在同一位置”重复时是一个好处。

In that case, a three-values comparator is a speed gain. 在这种情况下,三值比较器是速度增益。 But C++ uses a consistent definition of a comparator for sort and also for set and map , lower_bound and so on, which barely benefit from a three-value comparator (maybe save one comparison, maybe not). 但C ++使用比较器的一致定义进行排序,也使用setmaplower_bound等,这几乎不受三值比较器的影响(可能保存一个比较,也许不是)。 I'd guess they decided not to complicate their nice, general interface in the interests of specific or limited potential efficiency gains. 我猜他们决定不为了特定或有限的潜在效率增益而使他们漂亮的通用界面复杂化。

My guess in C++ it was done just to reduce code duplication: once you define a compare op on a class/type, you are not only able to compare those objects by simply writing a < b, but also gain the ability to sort sets of such objects. 我在C ++中的猜测只是为了减少代码重复:一旦你在类/类型上定义了一个比较操作,你不仅可以通过简单地写一个<b来比较这些对象,而且还可以对这些对象进行排序。这样的对象。

As for sorting, we only need less-than operator, why introduce additional stuff? 至于排序,我们只需要少于运营商,为什么要引入额外的东西? :) :)

if you're referring to std::sort(), its use only less() operator because it does not need to preserve relative ordering of equivalent element, so it will need just less() operator, and implicitly greater() operator. 如果你指的是std :: sort(),它只使用less()运算符,因为它不需要保留等效元素的相对排序,所以它只需要less()运算符和隐式big()运算符。

while std::stable_sort will preserve it, but it is slower. 虽然std :: stable_sort会保留它,但速度较慢。 it need less() operator and bidirectional iterator in exchange for equal() operator to construct "trivalue" compare function 它需要less()运算符和双向迭代器来交换equal()运算符来构造“trivalue”比较函数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 你如何编写一个operator()或者比trivalue-compare-function更少的函子 - How do you write a operator() or less-than-functor neater than a trivalue-compare-function 小于函数解引用指针 - Less-than function dereferencing pointers 为什么我的小于运算符没有处理? - Why isn't my less-than operator processing? 是否可以在 c++20 中使用比较运算符在枚举值之间建立小于大于顺序的关系 - Is it possible to make a less-than greater-than ordering relationship between enum values using comparison operator in c++20 不起作用:覆盖类的shared_ptr的默认小于号运算符 - Not working: override the default less-than operator of shared_ptr of a class 几次执行后,小于运算符无法正常工作 - less-than operator doesn't work properly after few executions 如果只定义了一个小于比较器,upper_bound() 是如何工作的? - How does upper_bound() work if only a less-than comparator is defined? 只用少于运算符测试等价? - Test for equivalence with only less than operator? 小于运算符不能作为成员函数重载 - Less than operator cannot be overloaded as member function 重载小于(&lt;)运算符以几种方式对对象进行排序 - overloaded less than (<) operator for sorting objects in several ways
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM