2016-05-08 12 views
0

Ich habe den folgenden Code, der gut funktioniert, aber jetzt brauche ich die Ausgabe sortiert, wann immer 1, 2 oder 3 in die Tastatur eingegeben wird. Ich nehme an, ich muss eine BubbleSort-Funktion erstellen, aber was genau geht in die Funktion? Dies ist meine erste Veröffentlichung, also vergib mir, wenn ich nicht die richtige Interpunktion und Einrückung habe, die auf dieser Seite Standard ist. Ich habe meinen gesamten Code eingeschlossen, weil ich nicht sicher war, wie ich sonst noch weitermachen könnte, alle Tipps sind mehr als willkommen. Wie sortiere ich Strukturen in einer Funktion

Das folgende ist mein Code:

// 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

Ich habe umsehen und fand Websites wie diese, aber im nicht sicher, wie Sie den Code in meinen Code zu implementieren: [link] (http://www.thecrazyprogrammer.com/2011/11/ c-program-to-sort-array-by-using-bubble.html) – Mark

+0

Haben Sie überlegt, die qsort-Funktion zu verwenden? https://www.google.co.uk/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwjXycyJr8vMAhXGOBoKHYDsBeEQFggdMAA&url=http%3A%2F%2Fwww.cplusplus.com%2Freference%2Fcstdlib% 2Fqsort% 2F & usg = AFQjCNEiK4bP9QPs4MnBLN9KqMqfZe3BgA & sig2 = aBrPF3M2cCOGV9uVVb9Clw –

+0

Und es gibt einige C++ Beispiele für bubblesort: http://www.cplusplus.com/forum/general/127295/. Möglicherweise können Sie qsort verwenden. Ich benutze es heutzutage öfter. –

Antwort

0

Wie in den Kommentaren darauf hingewiesen, verwenden std::sort. Darüber hinaus können Sie auch std::max_element verwenden, um das Maximum zu finden (und std::min_element, um das Minimum zu finden).

Hier ist displayMaxstd::sort verwenden und 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 Die Funktion wird ein Zeiger auf den maximalen Wert zurück im Bereich grades[i][0] zu grades[i][MAX_GRADES] gefunden. Beachten Sie, dass wir std::max_element Zeiger auf die Anfangs- und Endelemente angeben müssen, da max_element und die meisten anderen STL-Algorithmusfunktionen Iteratoren als Parameter verwenden und ein Zeiger ein Iteratortyp ist.

Dann sortieren wir die Schüler mit std::sort und geben das Prädikat, dass wir nach dem Maximalwert sortieren wollen, den wir in der Schleife oben festgelegt haben. Beachten Sie, dass die Sortierung in absteigender Reihenfolge durchgeführt wird, und dass durch das Prädikat

return s1.max > s2.max;

Mit anderen Worten kontrolliert wird, kehrt true wenn die s1 Maximalwert höher ist als der Maximalwert s2 (dh die Gegenstände in Ordnung sind) , sonst Rückgabe false (die Artikel sind außer Betrieb).

Sie würden eine ähnliche Funktion zum Ermitteln des Mindestwerts unter Verwendung von std::min_element schreiben. Um den Durchschnitt zu finden, können Sie std::accumulate verwenden, aber Sie haben eine Schleife bereits gesetzt, um den Durchschnitt zu erhalten, also denke ich, dass das auch funktionieren wird (mit der Änderung des Prädikats im Durchschnitt zu sortieren).

Live Demo Here

0

Verwendung std::sort mit einem benutzerdefinierten Prädikat:

#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... 
+0

Vielen Dank für die Antwort, aber vielleicht habe ich es nicht korrekt in meinen Code implementiert, aber die Ausgabe ist die gleiche. – Mark