【问题标题】:STL sort by multiple parameters C++STL按多参数排序C++
【发布时间】:2018-04-19 22:36:24
【问题描述】:

我有一个包含多个参数定义的对象 Studenti 的列表。 我想对这个学生列表进行排序,首先按他们的平均值,如果平均值相同,我会按字母顺序对它们进行排序。

在我的学生班级中,我声明了这个头函数: bool mediaDescrescator(const&, const&); 就是这样实现的:

bool Studenti::mediaDescrescator(const Studenti& a, const Studenti& b)
{
    if(a.medie_ != b.medie_)
    {
        return (a.medie_ > b.medie_);
    }

    return (a.nume_ > b.nume_);
}

medie_ 是 Studenti 的双重私人成员 nume_ 是 Studenti 的 std::string 私有成员

我主要有一个 Studenti 列表: std::list<Studenti> listaStud_ = {stud1, stud2, stud3, stud4, stud5};

函数调用: std::sort(listaStud_.begin(), listaStud_.end(), mediaDescrescator);

我的错误是:未在此范围内声明 mediaDescrescator。

我已经看到关于这种类型的其他主题,它们被声明为像我的一样,我什至尝试使用向量类型而不是列表。 mediaDescrescator 不带 () 调用,因为它必须作为函数指针或函数对象传递。

【问题讨论】:

    标签: c++ sorting c++11 stl


    【解决方案1】:

    mediaDescrescatorStudenti 的成员函数。它是在类的词法范围内定义的。所以你可以访问Studenti::mediaDescrescator,但不能访问mediaDescrescator。全局命名空间中没有名为 mediaDescrescator 的函数。

    另外,为了避免您可能面临的下一个错误,请确保它是一个 static 成员函数。毕竟,您不需要有效的实例来调用它。它不访问this 的任何成员变量。

    【讨论】:

      【解决方案2】:
      1. std::tie 返回引用的std::tuple

      2. std::tuple 定义了执行正确字典比较的比较运算符。

      所以您需要做的就是将Studentitie 一起转换为tuple - 然后比较元组。

      bool Studenti::mediaDescrescator(const Studenti& a, const Studenti& b)
      {
          return std::tie(a.medie_, a.nume_) > std::tie(b.medie_, b.nume_);
      }
      

      您可能会发现在您编写的类上提供一个名为 as_tuple() 的方法很有用:

      struct Studenti
      {
         // rest of class
      
         auto as_tuple() const { return std::tie(medie_, nume_); }
      };
      

      【讨论】:

        【解决方案3】:

        您的实施存在几个问题。第一个,也是您的编译器抱怨的一个是 mediaDescrescator 是在 Studenti 的范围内定义的,并且您尝试在全局范围内访问它,使用 Studenti::mediaDescrescator 获取指向它的指针。其次,mediaDescrescatorStudenti 的普通成员函数,因此需要在对象上调用它。这可以修复,例如通过使其成为静态成员函数,或使其采用一个参数并与当前对象进行比较。第三,std::sort 函数不能应用于std::list,因为它需要随机访问迭代器,而std::list 只提供双向迭代器。

        【讨论】:

        • 您在列表中的正确位置。我在其他主题中看到了这一点。但是我必须使用列表类型,如何在不复制向量类型的情况下应用这种类型的排序?
        • stackoverflow.com/a/2432946/104774 说使用std::list<>::sort()
        【解决方案4】:

        将函数声明更改为:

        bool mediaDescrescator(const Studenti& a, const Studenti& b)
        

        基本上在课外都有。

        如果您不想公开成员,请为它们编写 getter 函数并在排序中使用它们。

        【讨论】:

        • 最好在类外定义函数以便对类对象执行操作,即使使用 get 和 set?
        • 如果你只使用一次 sort 函数,我建议只在那个地方写一个 lambda 函数。最佳做法是在课堂上尽可能多地自我包含,但有时不值得花时间。
        【解决方案5】:

        首先,如果mediaDescrescator()是一个非静态成员函数,它只需要一个“其他”参数,因为它可以工作this成员。

        其次,lambdas 很容易让算法与成员函数一起工作(未经测试):

        listaStud_.sort([](const studenti& a, const studenti& b) { return a.mediaDescrescator(b); });
        

        您还可以结合 Richard Hodges 的回答(在本例中为公共成员)直接在 lambda 中实现 order 函数:

        listaStud_.sort([](const studenti& a, const studenti& b) { return std::tie(a.medie_, a.nume_) > std::tie(b.medie_, b.nume_); });
        

        根据 Johan 的回答:std::sort 不能在 std::list 上使用,请改用 std::list<>::sort(),就像在我的代码 sn-ps 中一样。

        【讨论】:

          猜你喜欢
          • 2018-10-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多