You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对存储学生信息的结构体数组使用sort()进行字母序排序

如何在const成员函数中实现按姓名排序输出学生成绩?

我是编程新手,这是本学期第二次作业、我的第二门编程课。我只会sort(array.begin(), array.end())的基础用法,不知道怎么用sort()把学生姓名按字母顺序排列。现在GradeBook类的outputGrades()是const函数,课程导师建议我在单独函数中使用sort(),但我搞不懂怎么实现。学生姓名可以预先初始化,不需要用户输入。


原代码

头文件(Gradebook2.h)

// Definition of class GradeBook that uses an array to store test grades.
#include<string>
#include<iostream>
#include<array>
#include<iomanip> //parameterized stream manipulators
#include<algorithm> //for .sort() .end()
using namespace std;

//GradeBook class definition
class GradeBook{
public:

  //constant number of students who took the test
  static const size_t students{10}; //note public data

  //constructor initializes courseName and grades array
  

    GradeBook(const string& name, const array <int, students>& gradesArray) //array of type int named gradesArray, size of 'students' (10)
    : courseName{name}, grades{gradesArray} {  }
    
    struct studentInfo
    {
        string studentName;
        int grade;
    };

  //function to set the course name
  void setCourseName(const string& name)
  {courseName = name; //store the course name
  } 

  //function to retrieve the course name
  const string& getCourseName() const {
    return courseName;
  }

  //display a welcome message to the GradeBook user
  void displayMessage() const{
    //call getCourseName to get the name of this GradeBooks course
    cout << "Welcome to the grade book for \n" << getCourseName() 
      << "!" << endl;
  }

  //perform various operations on the data (none modify the data)
  void processGrades() const {
    outputGrades(); //output grades array

    //call function getAverage to calculate the average grade
    cout << setprecision(2) << fixed;
    cout << "\nClass average is " <<getAverage() <<endl;

    //call functions getMinimum and getMaximum
    cout <<"Lowest grade is " << getMinimum()
    <<"\nHighest grade is "<< getMaximum() <<endl;
    
    outputBarChart(); //display grade distribution chart
  }

  //find minimum grade
  int getMinimum() const{
    int lowGrade{100}; //assume lowest grade is 100

    //loop through grades array
    for(int grade : grades){
      //if current grade lower than lowGrade, assign it to lowGrade
      if (grade < lowGrade){
          lowGrade = grade; //new lowest grade        
      }//end if
    }//end for

    return lowGrade;//return lowest grade
  }//end 'getMinimum'

  //find maximum grade
  int getMaximum() const {
    int highGrade{0};//assume highest grade is 0

    //loop through grades array
    for (int grade : grades){
      //if current grade higher than highGrade, assign it to highGrade
      if (grade > highGrade){
        highGrade = grade; //new highest grade        
      }//end if
    }//end for
    
    return highGrade; //return highest grade
  }//end 'getMaximum'

  //determine average grade for test
  double getAverage() const {
    int total{0};//initialize total

    //sum grades in array
    for (int grade : grades){
      total += grade;
    }//end for

    //return average of grades
    return static_cast<double>(total) / grades.size();
  }//end 'getAverage'

  //output bar chart displaying grade distribution
  void outputBarChart() const{
    cout << "\nGrade distribution:" <<endl;

    //stores frequency of grades in each range of 10 grades
    const size_t frequencySize{11};
    array<unsigned int, frequencySize> frequency{}; //init to 0s

    //for each grade, increment the appropriate frequency
    for (int grade : grades){
      ++frequency[grade / 10];
    }//end for

    //for each grade frequency, print bar in chart
    for (size_t count{0}; count < frequencySize; ++count){
      //output bar labels ("0-9:", ..., "90-99:", "100:")
      if (0 == count){
        cout << " 0-9: ";
      }//end if
      else if(10 == count){
        cout << " 100: ";
      }//end else if
      else{
        cout << count * 10 << "-" << (count * 10) + 9 << ": ";
      }//end else

      //print bar of asterisks
      for(unsigned int stars{0}; stars < frequency[count]; ++stars){
         cout <<'*'; 
      }//end for

      cout << endl; //start a new line of output
    }//end for
  }//end 'outputBarChart'
  
  //output the contents of the grades array
  void outputGrades() const{
        int i;
        studentInfo info[ students ]; 
        
        //collect names from user
        for(int i=0; i < students; i++)
        {
            cout << "\nEnter name of student " << i+1 << ": ";
            getline(cin, info[i].studentName);
        }//end for
        
        
        cout << endl << "\nStudent roster:\n";
        
            //output each students grades
            for (size_t student{0}; student < grades.size(); ++student){ 
                cout << "Student " << setw(2) << info[student].studentName << ": "
                << setw(3) << grades[student] << endl;
            }//end for

  }//end 'outputGrades'

private:

  string courseName; //course name for this grade book
  array<int, students> grades; // array of type int called 'grades' of size 'students'(10)
  
};//end class 'GradeBook'

主函数(GradeBook.cpp)

//GradeBook.cpp
#include<iostream>
#include <array>
#include<string>
#include<algorithm>
#include "Gradebook2.h" //GradeBook class definition


int main() {
  //array of student grades
  const array<int, GradeBook::students> grades{ 87, 68, 94, 100, 83, 78, 85, 91, 76, 87};
       
  string courseName{"COSC 1337"};

  GradeBook myGradeBook(courseName, grades);
  myGradeBook.displayMessage();
  myGradeBook.processGrades();

}//end main

解决方案

核心思路:outputGrades()是const函数,不能修改类的成员变量,但可以创建临时的学生信息集合,填充姓名和成绩后排序,排序操作不会影响类的原有状态,符合const函数的要求。导师说的“单独函数”就是把排序逻辑抽离,让代码更清晰。

步骤1:修改GradeBook类,添加排序辅助函数

在GradeBook类的public区域添加一个const成员函数,负责创建并排序学生信息,同时在头文件顶部添加#include <vector>:

#include<vector> // 添加vector头文件

// ... 原有类代码 ...

// 辅助函数:生成按姓名排序的学生信息列表
vector<studentInfo> getSortedStudentList() const {
    vector<studentInfo> studentList;
    // 绑定姓名和对应成绩(这里假设姓名已作为类成员存储)
    for (size_t i = 0; i < students; ++i) {
        studentList.push_back({studentNames[i], grades[i]});
    }
    // 按姓名字母序排序:用lambda表达式定义比较规则
    sort(studentList.begin(), studentList.end(), 
         [](const studentInfo& a, const studentInfo& b) {
             return a.studentName < b.studentName;
         });
    return studentList;
}

步骤2:给GradeBook添加姓名成员变量并修改构造函数

在private区域添加姓名数组,同时更新构造函数:

private:
  string courseName; //course name for this grade book
  array<int, students> grades; // array of type int called 'grades' of size 'students'(10)
  array<string, students> studentNames; // 新增:存储预先初始化的学生姓名
};

// 修改构造函数
GradeBook(const string& name, const array<int, students>& gradesArray, const array<string, students>& namesArray)
    : courseName{name}, grades{gradesArray}, studentNames{namesArray} {  }

步骤3:修改outputGrades()函数,使用排序后的列表

删除原有的用户输入逻辑,改为调用辅助函数获取排序后的列表并输出:

void outputGrades() const{
    // 获取排序后的学生信息
    auto sortedStudents = getSortedStudentList();
    
    cout << "\nStudent roster (sorted by name):\n";
    
    // 输出排序结果
    for (const auto& student : sortedStudents) { 
        cout << "Student " << setw(10) << student.studentName << ": "
             << setw(3) << student.grade << endl;
    }
}

步骤4:修改主函数,传入预先初始化的姓名数组

int main() {
  // 预先初始化学生姓名
  const array<string, GradeBook::students> studentNames{
      "Alice", "Bob", "Charlie", "David", "Eve", 
      "Frank", "Grace", "Henry", "Ivy", "Jack"
  };
  // 原有成绩数组
  const array<int, GradeBook::students> grades{ 87, 68, 94, 100, 83, 78, 85, 91, 76, 87};
       
  string courseName{"COSC 1337"};

  // 修改构造函数调用,传入姓名数组
  GradeBook myGradeBook(courseName, grades, studentNames);
  myGradeBook.displayMessage();
  myGradeBook.processGrades();

}//end main

关键说明

  1. const函数的限制:const成员函数不能修改类的成员变量,所以我们用临时的vector<studentInfo>来存储待排序的数据,排序操作只针对这个临时容器,不会影响类的原有状态。
  2. sort的自定义比较:默认sort会按对象的默认规则排序,这里用lambda表达式告诉sort,比较两个studentInfo对象时,按studentName的字母序(<运算符对string默认就是字母序比较)。
  3. 代码分离:把排序逻辑抽成getSortedStudentList()函数,符合导师“单独函数使用sort”的要求,也让outputGrades()只负责输出,职责更清晰。

内容的提问来源于stack exchange,提问作者Silver2L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 04:47:03