如何对函数中的结构进行排序
How do I sort structs in a function
我有下面的代码可以很好地工作,但现在每当在键盘上输入1、2或3时,我都需要对输出进行排序。我假设我必须创建一个BubbleSort函数,但函数中到底包含了什么?这是我第一次发帖,所以如果我没有正确的标点符号和缩进,请原谅我,这是本网站的标准。我包含了我的全部代码,因为我不是;我不知道该怎么办,任何建议都非常受欢迎。
以下是我的代码:
// Headers
#include <iostream> // cout, cin
#include <cstdlib> // exit()
#include <string> // strings
#include <fstream> // file processing
#include <iomanip> // stream manipulation
using namespace std;
// Global variables
const int MAX_STUDENTS = 25; // We will not process more than 25 students even if the file contains more
const int MAX_GRADES = 5; // Each student has exactly 5 grades
const string FILENAME = "NamesGrades.txt"; // The name of the file that you will read
// Function declarations
int loadStudentNamesGrades(struct Student[], int grades[][MAX_GRADES], string fileName, int maxStudents);
void displayAverages(struct Student[], int grades[][MAX_GRADES], int studentCount);
void displayMax(struct Student[], int grades[][MAX_GRADES], int studentCount);
void displayMin(struct Student[], int grades[][MAX_GRADES], int studentCount);
string getLetterGrade(double grade);
int getLongestNameLength(int studentCount);
struct Student
{
string name; //name of student
double average; //average grades for student
int max; //holds max grade for student
int min; //holds min grade for student
};
Student studentNum[MAX_STUDENTS]; //creates array of struct Student
int main()
{
int studentCount = 0; //assigned 0 to # of students
int grades[MAX_STUDENTS][MAX_GRADES]; //array for table of grades for students
//string students[MAX_STUDENTS]; //array for list of students
char choice; //user input is assigned here
// Get students and grades
studentCount = loadStudentNamesGrades(studentNum, grades, FILENAME, MAX_STUDENTS);
//Menu for choices
do
{
// present the menu
cout << "nTemperature Report Program" << endl << endl;
cout << "t1. Display Average Grades" << endl;
cout << "t3. Display Mininum Grades" << endl;
cout << "t4. Quit Program" << endl;
cout << "nEnter your choice (1-4): ";
cin >> choice;
// the choice is then executed
switch (choice)
{
case '1': // average
displayAverages(studentNum, grades, studentCount);
break;
case '2': // max
displayMax(studentNum, grades, studentCount);
break;
case'3': // min
displayMin(studentNum, grades, studentCount);
break;
case'4': // exit
break;
default: // Any other choice besides the given choices
cout << "Invalid option. Please try again." << endl << endl;
}
if (choice != '4')
{
cout << endl;
system("PAUSE");
system("CLS");
}
} while (choice != '4');
// End of program
cout << endl;
return 0;
}
//uses info in file
int loadStudentNamesGrades(Student[], int grades[][MAX_GRADES], string fileName, int maxStudents)
{
ifstream inFile;
string studentName, //student first name
lastName; //student last name
int numStudents = 0;
//opens file
inFile.open(fileName.c_str());
if (inFile.fail())
{
cout << "Could not open file" << endl;
system("PAUSE");
exit(1);
}
//loop to get names of students and grade
for (int i = 0; i < maxStudents && (inFile >> studentName >> lastName); i++, numStudents++)
{
studentNum[i].name = studentName + " " + lastName;
//gets the grade
for (int j = 0; j < MAX_GRADES; j++)
{
inFile >> grades[i][j];
}
//students[i] = studentName + " " + lastName;
}
//closes file
inFile.close();
//returns actual number of students
return numStudents;
}
//code for average
void displayAverages(Student[], int grades[][MAX_GRADES], int studentCount)
{
//double average; //average grade for students
int sum; //total grade(cummulative/accumulator)
int maxLength = getLongestNameLength(studentCount);
//will set decimal place to one point
cout << setprecision(1) << fixed << showpoint;
//header
cout << "nnGrade Averagesn";
cout << setw(maxLength + 1) << left << "Name"
<< setw(8) << right << "Average"
<< setw(10) << "Grade" << endl;
//code to calculate average
for (int i = 0; i < studentCount; i++)
{
cout << setw(maxLength + 1) << left << studentNum[i].name;
sum = 0;
for (int j = 0; j < MAX_GRADES; j++)
{
sum += grades[i][j];
}
studentNum[i].average = (double)sum / MAX_GRADES;
cout << setw(8) << right << studentNum[i].average
<< setw(10) << getLetterGrade(studentNum[i].average) << endl;
}
}
//displays max grade for each student
void displayMax(Student[], int grades[][MAX_GRADES], int studentCount)
{
//int maxGrade; //max grade is stored here
int maxLength = getLongestNameLength(studentCount);
//header
cout << "nnMax Gradesn";
cout << setw(maxLength + 1) << left << "Name"
<< setw(4) << right << "Max"
<< setw(10) << "Grade" << endl;
//displays students and each of their max grade
for (int i = 0; i < studentCount; i++)
{
cout << setw(maxLength + 1) << left << studentNum[i].name;
studentNum[i].max = grades[i][0];
for (int j = 1; j < MAX_GRADES; j++)
{
if (studentNum[i].max < grades[i][j])
studentNum[i].max = grades[i][j];
}
cout << setw(4) << right << studentNum[i].max
<< setw(10) << getLetterGrade(studentNum[i].max) << endl;
}
}
//displays min grade for each student
void displayMin(Student[], int grades[][MAX_GRADES], int studentCount)
{
//int minGrade; //holds min grade
int maxLength = getLongestNameLength(studentCount);
//header
cout << "nnMin Gradesn";
cout << setw(maxLength + 1) << left << "Name"
<< setw(4) << right << "Min"
<< setw(10) << "Grade" << endl;
//displays students and min grade
for (int i = 0; i < studentCount; i++)
{
cout << setw(maxLength + 1) << left << studentNum[i].name;
studentNum[i].min = grades[i][0];
for (int j = 1; j < MAX_GRADES; j++)
{
if (studentNum[i].min > grades[i][j])
studentNum[i].min = grades[i][j];
}
cout << setw(4) << right << studentNum[i].min
<< setw(10) << getLetterGrade(studentNum[i].min) << endl;
}
}
//guidline for what letter grade to output for each numerical grade
string getLetterGrade(double grade)
//changed it from char to string because it wouldnt compile
{
if (grade >= 90)
return "A";
else if (grade >= 80)
return "B";
else if (grade >= 70)
return "C";
else if (grade >= 60)
return "D";
else
return "F";
}
//code for table to know what length to use for spacing
int getLongestNameLength(int studentCount)
{
int maxLength = 0;
for (int i = 0; i < studentCount; i++)
{
if (studentNum[i].name.length() > maxLength)
maxLength = studentNum[i].name.length();
}
return maxLength;
}
正如注释中所指出的,使用std::sort
。此外,您还可以使用std::max_element
来查找最大值(使用std::min_element
来查找最小值)。
这里是使用std::sort
的displayMax
和std::max_element
void displayMax(Student* students, int grades[][MAX_GRADES], int studentCount)
{
//get max grade for each student
for (int i = 0; i < studentCount; i++)
students[i].max = *std::max_element(&grades[i][0], &grades[i][MAX_GRADES);
// sort students based on max
std::sort(students, students + studentCount, [](const Student& s1, const Student& s2)
{ return s1.max > s2.max;});
// output results
cout << "n";
for (int i = 0; i < studentCount; ++i)
cout << students[i].name << " " << students[i].max << "n";
}
max_element
函数将返回指向范围grades[i][0]
到grades[i][MAX_GRADES]
中的最大值的指针。注意,我们必须为std::max_element
提供指向开始项和结束项的指针,因为max_element
和大多数其他STL算法函数使用迭代器作为参数,指针是迭代器类型。
然后,我们使用std::sort
对学生进行排序,并根据上面循环中设置的最大值给出要排序的谓词。请注意,排序是按降序进行的,这是由谓词控制的
return s1.max > s2.max;
换句话说,如果s1的最大值高于s2的最大值(表示项目有序),则返回true
,否则返回false
(项目无序)。
您可以编写一个类似的函数来使用std::min_element
查找最小值。要找到平均值,可以使用std::accumulate
,但已经设置了一个循环来获得平均值,所以我想这也会很好(将谓词更改为按平均值排序)。
这里的实时演示
将std::sort
与自定义谓词一起使用:
#include <algorithm>
#include <string>
#include <vector>
struct Student
{
std::string name; //name of student
double average; //average grades for student
int max; //holds max grade for student
int min; //holds min grade for student
};
void sort_by_name(std::vector<Student>& v)
{
auto by_name = [](const Student& l, const Student& r)
{
return l.name < r.name;
};
std::sort(std::begin(v), std::end(v), by_name);
}
void sort_by_average(std::vector<Student>& v)
{
auto by_average = [](const Student& l, const Student& r)
{
return l.average < r.average;
};
std::sort(std::begin(v), std::end(v), by_average);
}
// ... and so on...
- 将结构向量排序为子组
- 带有枚举方向/类型的气泡排序结构数组
- C++对结构向量进行排序
- 在C++中对结构向量进行排序时出现问题
- 按字母顺序对结构内数组变量中的名称进行排序
- 保持排序的数据结构,允许log N插入时间,并且可以返回我在log N中查找的元素的索引
- 使用选择排序对数组数据结构进行排序,但它不起作用
- 对结构向量进行两次排序
- C++使用QuickSort对数组结构进行排序
- 如何选择排序一些结构
- 对结构int成员进行排序
- 在排序链表中插入结构并将其写入二进制文件
- 对坐标结构的向量进行排序
- C++ 中优先级队列的结构排序条件
- C++ MDC final-在字符类型的数组结构中按字母顺序对记录中的名称进行排序
- 按字母顺序对结构数组进行排序
- C++结构排序性能
- 自定义结构排序不起作用
- std::向量使结构排序变慢?C++
- 数据结构-排序队列链表c++