我有以下代码可以正常工作,但现在我需要在键盘输入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 << "\n\nGrade Averages\n";
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 << "\n\nMax Grades\n";
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 << "\n\nMin Grades\n";
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;
}
答案 0 :(得分:0)
将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...
答案 1 :(得分:0)
正如评论中所指出的,使用std::sort
。此外,您还可以使用std::max_element
查找最大值(std::min_element
查找最小值。)
以下displayMax
使用std::sort
和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
,但是你已经设置了一个循环来获得平均值,所以我想这也可以正常工作(通过改变谓词来平均排序)。