1

下面的函数是我的比较函数。虽然直接比较两个字符成功地对数组进行了分类,但使用 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 会导致位置颠倒,例如 alan, richard, byron, sarah -> sarah, byron, richard, alan。

4

4 回答 4

6

std::string::compare返回一个int你打算比较的,0以给出一个实际的排序顺序。例如,要检查是否a.name小于b.name(根据 给出的顺序compare),您可以编写:

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

您当前编写它的方式将返回true任何不相等的字符串,这不是有效的严格弱排序,正如std::sort所要求的那样。

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

return a.name < b.name;
于 2013-03-12T22:18:31.940 回答
2

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

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

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

那么,您的代码中发生了什么?如果names 相等,则compare返回 0,它被强制转换为false。否则,您将得到一个非零整数,该整数将被强制转换为true. 由于std::sort没有绝对指定排序算法,我们不能说为什么你要精确地得到某个顺序,但本质上,std::sortstd::swap随机的对象(伪)。

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

于 2013-03-12T22:22:48.083 回答
1

sort 期望它的比较器表现得像 operator<,而 std::string::compare 表现得像这里描述的那样。

于 2013-03-12T22:19:26.870 回答
1

您正在返回一个intstd::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;
};

并摆脱您试图完全制造的自定义比较器。有了这个,您可以使用 just 对一组学生进行排序std::sort(students.begin(), students.end()),因为默认比较器 ,std::less<YourType>将在排序时进行比较时调用您的运算符。

于 2013-03-12T22:21:34.063 回答