【问题标题】:Sorting a Class [closed]对班级进行排序[关闭]
【发布时间】:2021-12-15 15:13:39
【问题描述】:

所以,我正在学习 C++ 中的课程,我创建了两个课程,一个用于包含班级学生列表的大学,我设法创建了学生,并向班级介绍了一些值,但现在我想排序按学生编号的班级学生,我尝试使用排序功能,但我没有成功。我将在下面留下我的代码,请提供一些好的提示和建议,以便我可以改进我的代码。谢谢

ma​​in.css

#include <iostream>
#include "university.h"
#include "students.h"

using namespace std;

int main() {

    university univ = university();

    return 0;
}

university.h

#pragma once
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
#include "students.h"

using namespace std;


class university
{
private:
   list<students> lstudents;
   list<students>::iterator itstudents;

public:

   university();
   void setStudents(list<students> lstudents);
   void registerStudent();
   void list();
   void average();
   //void sortstudents();

};

university.cpp

#include "university.h"

using namespace std;

university::university() { //constructor
   string resp = "s";
   int op;
   bool out = true;

   cout << "Enter Students:" << endl;

   while (resp != "n")
   {
       this->registerStudent();
       cout << "Continue inserting? (s/n)" << endl;
       cin >> out;
       cin.ignore();
   }

   while (out)
   {
       cout << "What you Want to do? (1- List Students 2- Sudent Average 3- Sort Students by Number 4- Leave)" << endl;
       cin >> op;
       switch (op)
       {
       case 1:
           this->list();
           break;
       case 2:
           this->average();
           break;
           /*case 3:
               this->sortStudents();
               break;*/

       case 4:
           out = false;
           break;
       };
   }

}


void university::setStudents(list<students> lstudents) {
   this->lstudents = lstudents;
}


void university::registerStudent()
{
   lstudents.push_back(students());
}

void university::list()
{
   int sum = 0;
   cout << "------------------------- LIST STUDENTS -------------------------------\n\n";
   cout << left << setw(11) << "Number"
       << left << setw(30) << "Name"
       << left << setw(30) << "Course"
       << left << setw(10) << "Average";
   cout << "\n";

   for (itstudents = lstudents.begin(); itstudents != lstudents.end(); itstudents++)
   {
       (*itstudents).list();
       ++sum;
   }
   //cout << "Total de pacientes:" << somatorio << endl;
   //somatorio = 0;

}

void university::average()
{
   int sum = 0;
   double average = 0;


   for (itstudents = lstudents.begin(); itstudents != lstudents.end(); itstudents++)
   {
       average += (*itstudents).getaverage();
       ++sum;
   }
   cout << "Average:" << average / sum << endl;

}


//void university::sortstudents() {
//   sort(lstudents.begin(), lstudents.end(), &students::compare);
//}

students.h 如您所见,注释代码是我对班级学生的编号进行排序的尝试

#pragma once
#include <iomanip>
#include <algorithm>
#include <list>
#include "university.h"


using namespace std;


class students {
private:
   std::string name;
   std::string course;
   int number;
   double average;
public:
   //friend bool operator<(estudantes& left,estudantes& right) { return left.matricula < right.matricula; };
   students();
   void list();
   double getaverage();
   int getnumber();
   //bool compare(estudantes a, estudantes b);
};

students.cpp

#include "students.h"

students::students() {

   cout << "Name: ";
   getline(cin, name);
   cout << "Course: ";
   getline(cin, course);
   cout << "Number: ";
   cin >> this->number;
   cout << "Average: ";
   cin >> this->average;

}

void students::list() {

   cout << left << setw(11) << number;
   cout << left << setw(30) << name;
   cout << left << setw(30) << course;
   cout << left << setw(10) << average << endl;
}

double students::getaverage() {
   return average;
}

int students::getnumber() {
   return number;
}

//bool estudantes::compare(student a, student b) {
//
// if (a.number < b.number)
//       return 1;
//   else
//       return 0;
//}

【问题讨论】:

  • 你能比“但我没有成功”更具体吗?
  • 就我而言,这不是minimal, reproducible example
  • 您正在尝试使用std::sortstd::list 进行排序。 std::sort 需要一个随机迭代器,但std::list 只提供一个前向迭代器。但是,std::list 提供了自己的 sort 方法。改用它。
  • std::sort 要求你给它一对随机访问迭代器。您将您的学生存储在 std::list 中,它不提供他们。您的比较器也有一些问题,它是students 的非静态成员函数,但最重要的是std::sort 依赖于能够交换不相邻的容器元素,而你不能使用std::list
  • @Eljay 这是LegacyBidirectionalIterator,但您的总体观点仍然有效。

标签: c++ class sorting


【解决方案1】:

使它独立和固定。我会发布然后解释,因为人们肯定会过早地结束这个问题:

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <list>
#include <string>

class students {
  private:
    std::string name;
    std::string course;
    int         number;
    double      average;

  public:
    // friend bool operator<(students& left,students& right) { return
    // left.matricula < right.matricula; };
    students();
    void   list();
    double getaverage();
    int    getnumber();
    static bool compare(students const& a, students const& b);
};

students::students()
{
    std::cout << "Name: "; getline(std::cin, name);
    std::cout << "Course: "; getline(std::cin, course);
    std::cout << "Number: "; std::cin >> this->number;
    std::cout << "Average: "; std::cin >> this->average;
}

void students::list() {
   std::cout << std::left << std::setw(11) << number;
   std::cout << std::left << std::setw(30) << name;
   std::cout << std::left << std::setw(30) << course;
   std::cout << std::left << std::setw(10) << average << std::endl;
}

double students::getaverage() {
   return average;
}

int students::getnumber() {
   return number;
}

bool students::compare(students const& a, students const& b) {
    return a.number > b.number;
}

class university {
  private:
    std::list<students>           lstudents;
    std::list<students>::iterator itstudents;

  public:
    university();
    void setStudents(std::list<students> lstudents);
    void registerStudent();
    void list();
    void average();
    void sortStudents();
};

university::university() // constructor
{
    std::string resp = "s";
    int         op;
    bool        out = true;

    std::cout << "Enter Students:" << std::endl;

    while (resp != "n") {
        this->registerStudent();
        std::cout << "Continue inserting? (s/n)" << std::endl;
        std::cin >> out;
        std::cin.ignore();
    }

    while (out) {
        std::cout << "What you Want to do? (1- List Students 2- Sudent Average "
                     "3- Sort Students by Number 4- Leave)"
                  << std::endl;
        std::cin >> op;
        switch (op) {
        case 1: this->list(); break;
        case 2:
            this->average();
            break;
        case 3: this->sortStudents(); break;
        case 4: out = false; break;
        };
    }
}

void university::setStudents(std::list<students> lstudents) {
   this->lstudents = lstudents;
}


void university::registerStudent()
{
   lstudents.push_back(students());
}

void university::list()
{
   int sum = 0;
   std::cout << "------------------------- LIST STUDENTS -------------------------------\n\n";
   std::cout << std::left << std::setw(11) << "Number"
       << std::left << std::setw(30) << "Name"
       << std::left << std::setw(30) << "Course"
       << std::left << std::setw(10) << "Average";
   std::cout << "\n";

   for (itstudents = lstudents.begin(); itstudents != lstudents.end(); itstudents++)
   {
       (*itstudents).list();
       ++sum;
   }
   //std::cout << "Total de pacientes:" << somatorio << std::endl;
   //somatorio = 0;

}

void university::average()
{
   int sum = 0;
   double average = 0;


   for (itstudents = lstudents.begin(); itstudents != lstudents.end(); itstudents++)
   {
       average += (*itstudents).getaverage();
       ++sum;
   }
   std::cout << "Average:" << average / sum << std::endl;

}

void university::sortStudents() {
    lstudents.sort(&students::compare);
}

int main() {

    university univ = university();

    return 0;
}

说明

有很多问题。

  1. students::compare 是一个非静态成员函数,这意味着它只能在 student 实例上调用。要根据需要使用 2 参数排序谓词,只需将其设为静态即可

  2. 实现可能更惯用:

    bool students::compare(students const& a, students const& b) {
        return a.number > b.number;
    }
    

    这避免了将1 当作true 使用的C 主义,以及无用的if/else

  3. 您使用了std::sort,但它需要随机访问迭代器。 std::list 没有提供。因此std::list::sort 存在:

    void university::sortStudents() {
        lstudents.sort(&students::compare);
    }
    

在许多其他风格问题中:

  • 不要using namespace std;
  • 不要在构造函数中做副作用?
  • 错误检查 IO
  • 避免被零除(例如在average()

【讨论】:

猜你喜欢
  • 2014-10-20
  • 2017-01-25
  • 1970-01-01
  • 2016-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-08
相关资源
最近更新 更多