[英]Sort compare function weird behavior
The function below is my compare function. 下面的功能是我的比较功能。 While comparing directly two characters successfully assorts the array, using the std::string compare function doesn't.
当直接比较两个字符成功地将数组分类时,使用std :: string比较函数不会。
int compare (student a, student b) {
return a.name.compare(b.name);
return a.name[0] < b.name[0];
}
The call 通话
sort(data.begin(), data.end(), compare);
Where data is defined as vector <student> data;
其中数据定义为
vector <student> data;
Have you got any ideas why is it that std::compare doesn't sort it? 您有什么主意,为什么std :: compare不对它排序?
PS: std::compare results in inverting the positions, eg alan, richard, byron, sarah -> sarah, byron, richard, alan. PS:std :: compare会反转位置,例如alan,richard,byron,sarah-> sarah,byron,richard,alan。
std::string::compare returns an int
which you are meant to compare to 0
to give an actual sort order. std :: string :: compare返回一个
int
,您应该将其与0
进行比较以给出实际的排序顺序。 For example, to check if a.name
is less than b.name
(according to the ordering given by compare
) you would write: 例如,要检查
a.name
是否小于b.name
(根据compare
给出的顺序),可以这样写:
return a.name.compare(b.name) < 0;
The way that you have currently written it will return true
for any unequal strings, which is not a valid strict weak ordering , as required for std::sort . 您当前编写的方式将对任何不相等的字符串返回
true
,这不是有效的严格弱排序 ,如std :: sort所要求。
There is no good reason to use compare
here at all, as std::string has an operator< that gives an equivalent ordering of the two strings: 根本没有充分的理由在这里使用
compare
,因为std :: string有一个operator < ,它给出两个字符串的等效顺序:
return a.name < b.name;
Have a read through the std::sort reference at cppreference.com ; 通读cppreference.com上的std :: sort参考 ; it clearly explains that the comparison function should return a
bool
which indicates the first argument is less than the second. 它清楚地说明比较函数应该返回
bool
,该bool
指示第一个参数小于第二个参数。
In this case, you would call it like this: 在这种情况下,您可以这样称呼它:
std::sort(data.begin(), data.end(), [](student const& a, student const& b) {
return a.name < b.name;
})
So, what's happening in your code? 那么,您的代码中发生了什么? If the
name
s are equal, compare
returns 0, which is cast to false
. 如果
name
s相等,则compare
返回0,将其强制转换为false
。 Otherwise, you will get a non-zero integer, which will be cast to true
. 否则,您将获得一个非零整数,该整数将被强制转换为
true
。 Since the sorting algorithm in std::sort
isn't specified absolutely, we can't say why you are getting a certain order precisely, but essentially, std::sort
is std::swap
ing objects (pseudo) randomly. 由于
std::sort
的排序算法不是绝对指定的,因此我们无法说出为什么要精确地获得某个顺序,但从本质std::sort
, std::sort
是std::swap
对象(伪)。
So, should you define a compare
function? 那么,您应该定义一个
compare
函数吗? IMHO, no. 恕我直言,不。 It is quite easily to define for some basic types, but as far as I can tell, it doesn't really appear in any algorithms.
定义一些基本类型非常容易,但是据我所知,它实际上并没有出现在任何算法中。 It is a C-ism, and unfortunately, C++ kept it.
这是一种C-ism,不幸的是,C ++保留了它。 If appropriate, define a strict weak ordering using
operator<
instead, or just define comparators when needed. 如果合适,请使用
operator<
定义严格的弱排序 ,或者仅在需要时定义比较器。
排序预计其比较的行为类似于运营商<,而的std :: string ::所描述的行为比较这里 。
You're returning an int
which std::sort
sees as either "same" or "not same". 您将返回一个
std::sort
视为“相同”或“不相同”的int
。 You should be returning this: 您应该返回此:
return a.name.compare(b.name) < 0;
And change the return type to bool
并将返回类型更改为
bool
However, have you considered this instead: 但是,您是否考虑过这一点:
class student
{
public:
... members ...
bool operator <(const student& s) const
{
return name < s.name;
}
private:
std::string name;
};
And get rid of the custom comparator you're trying to fabricate entirely . 并摆脱您试图完全制造的自定义比较器。 With this you can then sort a collection of students using just
std::sort(students.begin(), students.end())
, since the default comparator, std::less<YourType>
, will invoke your operator when doing comparisons while sorting. 然后,您可以仅使用
std::sort(students.begin(), students.end())
对学生的集合进行std::sort(students.begin(), students.end())
,因为默认比较器std::less<YourType>
会在进行比较时调用您的运算符在排序时。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.