排序比较函数奇怪的行为

时间:2013-03-12 22:15:27

标签: c++ sorting

以下功能是我的比较功能。直接比较两个字符成功地匹配数组,使用std :: string比较函数不会。

int compare (student a, student b) {
  return a.name.compare(b.name);
  return a.name[0] < b.name[0];
}

电话

sort(data.begin(), data.end(), compare);

数据定义为vector <student> data;

你有什么想法,为什么std :: compare不排序呢?

PS:std :: compare导致反转位置,例如艾伦,理查德,拜伦,萨拉 - &gt;莎拉,拜伦,理查德,阿兰。

4 个答案:

答案 0 :(得分:6)

std::string::compare会返回int,您要与0进行比较以提供实际的排序顺序。例如,要检查a.name是否小于b.name(根据compare给出的顺序),您可以写下:

return a.name.compare(b.name) < 0;

您当前编写的方式将返回true以查找strict weak ordering所需的任何不相等的字符串,这不是有效的std::sort

这里没有充分理由使用compare,因为std::string有一个operator<,它给出了两个字符串的等效排序:

return a.name < b.name;

答案 1 :(得分:2)

阅读std::sort reference at cppreference.com;它清楚地解释了比较函数应该返回bool,表示第一个参数小于第二个参数。

在这种情况下,您可以这样称呼它:

std::sort(data.begin(), data.end(), [](student const& a, student const& b) {
    return a.name < b.name;
})

那么,您的代码中发生了什么?如果name s相等,compare将返回0,这将转换为false。否则,您将获得一个非零整数,该整数将转换为true。由于std::sort中的排序算法没有明确指定,我们无法说明为什么要精确地获得某个顺序,但实质上,std::sortstd::swap对象(伪)随机

那么,你应该定义一个compare函数吗?恕我直言,没有。很容易定义一些基本类型,但据我所知,它并没有真正出现在任何算法中。它是一个C-ism,不幸的是,C ++保留了它。如果合适,请使用operator<来定义严格弱排序,或者在需要时定义比较器。

答案 2 :(得分:1)

sort期望其比较器的行为类似于operator&lt;,而std :: string :: compare的行为与描述here相同。

答案 3 :(得分:1)

您将返回int std::sort视为“相同”或“不相同”的return a.name.compare(b.name) < 0; 。你应该回来了:

bool

并将返回类型更改为class student { public: ... members ... bool operator <(const student& s) const { return name < s.name; } private: std::string name; };

但是,你有没有考虑过这个:

std::sort(students.begin(), students.end())

摆脱你试图制作完全的自定义比较器。有了这个,您可以使用std::less<YourType>对学生集合进行排序,因为默认比较器{{1}}将在排序时进行比较时调用您的操作员。