Bubble sort function for last names, in alphabetical order

For this project I am struggling to create my function that sorts a list of full names by last names. I know that I will need to use another bubble sort as I have done for the previous functions, but I am not too sure how to compare only the last names. Please help and explain.

Here is the code:
Where it says provide implementation is where I am stuck on


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#include <iostream>
#include <vector>
#include <string>
#include <locale>
#include <iomanip>
using namespace std;

void PrintWelcome();
void GetNumberOfStudents(int &numOfStudents);
void PrintMenu();
char GetUserSelection();
void PrintSummary(const vector<string> &students, const vector<double> &grades);
void AddStudent(vector<string> &students, vector<double> &grades);
void RemoveStudent(vector<string> &students, vector<double> &grades);
void SortByFirstName(vector<string> &students, vector<double> &grades);
void SortByLastName(vector<string> &students, vector<double> &grades);
void SortByGrade(vector<string> &students, vector<double> &grades);

int main() {
    const char QUIT = 'q';
    const char ADD = 'a';
    const char REMOVE = 'r';
    const char PRINT = 'p';
    const char MENU = 'm';

    string thankYou = "Thank you for entering your students information!\n";
    string notValid = "Not a valid selection.\n";
    char selection;

    int numOfStudents;

    vector<string> students;
    vector<double> grades;

    //Print the Welcome Message
    PrintWelcome();
    //Get Number of Students
    GetNumberOfStudents(numOfStudents);
    //Add the total number of students to the student and grades vectors
    for(int i = 0; i <numOfStudents; i++){
        AddStudent(students, grades);
    }
    //Print thank you message
    cout << thankYou;
    //Print the Roster Menu
    PrintMenu();
    //Get the users selection
    selection = GetUserSelection();

    while(selection != QUIT){
        if(selection == ADD){
            AddStudent(students, grades);
        }
        else if(selection == REMOVE){
            RemoveStudent(students, grades);
        }
        else if(selection == PRINT){
            PrintSummary(students, grades);
        }
        else if(selection == MENU){
            PrintMenu();
        }
        else if(selection == 'f')
        {
           SortByFirstName(students, grades);
        }
        else if(selection == 'l')
        {
           SortByLastName(students, grades);
        }
        else if(selection == 'g')
        {
           SortByGrade(students, grades);
        }
        else{
            cout << notValid;
        }
        selection = GetUserSelection();
    }



}

void PrintWelcome(){
    string welcome = "Welcome to the student roster!\n";
    cout << welcome;
}

void GetNumberOfStudents(int &numOfStudents){
    string numOfStudentsQuestion = "How many students are in your class?:\n";
    cout << numOfStudentsQuestion;
    cin >> numOfStudents;
}

void PrintMenu(){
    string menu = "Please choose one of the following options:\n"
                  "a: add a student\n"
                  "r: remove a student\n"
                  "p: print the class summary\n"
                  "m: print menu\n"
                  "f: sort - first name\n"
                  "l: sort - last name\n"
                  "g: sort - grade\n"
                  "q: quit program\n";

    cout << menu;
}
char GetUserSelection(){
    string selectionString = "selection:\n";
    char selection;
    cout << selectionString;
    cin >> selection;
    return selection;
}
void PrintSummary(const vector<string> &students, const vector<double> &grades){
    string summaryHeading = "Class Summary\n"
                            "------------------------\n";
    string nameGradeHeading = "Name                Grade\n"
                              "---------           --------\n";
    string numOfStudentsString = "Number of Students:\n"
                                 "-------------------\n";
    string averageGradeString = "Average Grade:\n"
                                "--------------\n";
    double sum = 0.0;
    double average = 0.0;
    int numOfStudents = students.size();
    cout << endl;
    cout << summaryHeading << nameGradeHeading;
    for(int i = 0; i < students.size(); i++){
        sum += grades.at(i);
        cout << left << setw(20) << students.at(i) << setprecision(2) << fixed << grades.at(i) << endl;
    }
    cout << numOfStudentsString << numOfStudents << endl;
    cout << averageGradeString << setprecision(2) << fixed << sum/numOfStudents << endl;
    cout << endl;
}
void AddStudent(vector<string> &students, vector<double> &grades){
    string studentInfo = "Please enter student (First Last Grade) info:\n";
    string firstName, lastName;
    double grade;

    cout << studentInfo;
    cin >> firstName >> lastName >> grade;
    students.push_back(firstName + " " + lastName);
    grades.push_back(grade);
}
void RemoveStudent(vector<string> &students, vector<double> &grades){
    string removeStudent = "Please enter students first and last name";
    string firstName, lastName;

    cout << removeStudent;
    cin >> firstName >> lastName;
    string fullName = firstName + " " + lastName;
    for(int i = 0; i < students.size(); i++){
        if(students.at(i) == fullName) {
            students.erase(students.begin() + i);
            grades.erase(grades.begin() + i);
            cout << "Removing: " << fullName;
        }
    }
}
void SortByFirstName(vector<string> &students, vector<double> &grades){
   cout << "Sorting by first name" << endl;
   
   int i, j;
   string temp;
   int smallestIndex;
   double temp_grade;
   
   for(i = 0; i < students.size(); ++i)
   {
      smallestIndex = i;
      for(j = i + 1; j < students.size()-1; ++j)
      {
         if (students.at(j) < students.at(smallestIndex))
         {
            smallestIndex = j;
         }
      }
       temp_grade = grades.at(i);
       grades.at(i) = grades.at(smallestIndex);
       grades.at(smallestIndex) = temp_grade;
       
       temp = students.at(i);
       students.at(i) = students.at(smallestIndex);
       students.at(smallestIndex) = temp;
      
   }

}
void SortByLastName(vector<string> &students, vector<double> &grades){
    cout << "Sorting by last name" << endl;
    /*Provide Implementation*/

}
void SortByGrade(vector<string> &students, vector<double> &grades){
    cout << "Sorting by grade" << endl;
    
    int i, j, smallestIndex; 
    double temp;
    string temp_student;
    
    
    for(i = 0; i < students.size(); ++i)
    {
       smallestIndex = i;
       for(j = i + 1; j < students.size()-1; ++j)
       {
          if(grades.at(j) < grades.at(smallestIndex))
          {
             smallestIndex = j;
          }
       }
       temp = grades.at(i);
       grades.at(i) = grades.at(smallestIndex);
       grades.at(smallestIndex) = temp;
       
       temp_student = students.at(i);
       students.at(i) = students.at(smallestIndex);
       students.at(smallestIndex) = temp_student;
    }
}




this is the project info:

The class roster program is working really well. However, it would be nice to be able to sort students based on first name, last name, or their grade. I would like a program where I can choose how my roster is sorted and then print out the class summary

Specification

I have provided a template main.cpp for you to edit
You only have to add code to the areas that say /*Provide Implementation*/. You will find this in three functions, and in the selection handling portion of main
Note: You are not allowed to change any of the function signature (ie. add or edit parameter names and types, or change the function name or its return type)
Note: For sorting you must implement a Selection Sort
Video Explanation Selection Sort
Note: If two elements are equal do not swap the elements
SortByFirstName(vector &students, vector &grades) - option f
Sorts students and grades by the students first name
SortByLastName(vector &students, vector &grades) - option l (lowercase L)
Sorts students and grades by the students last name
SortByGrade(vector &students, vector &grades) - option g
Sorts students and grades by the students grade
You will also need to add code which calls the functions if the user selects to sort using that sort by function
You can find it in the code by searching for /*Provide Implementation for other menu options*/
> Note: You are not allowed to change any of the function signature
Your teacher seems to be teaching you frustration programming.
Showing you how to do it badly before hopefully showing you how to do it well.
C++ has much to offer without these silly blind alley diversions.

> I know that I will need to use another bubble sort
But you're told to (and already provided with an example and a video) of selection sort.
So use the same algorithm given in SortByFirstName.

> students.push_back(firstName + " " + lastName);
This is your PITA.

Because where you do this to compare first names
if (students.at(j) < students.at(smallestIndex))

Every time you want to compare a last name, you have to do something like
string lastname = students.at(j).substr(students.at(j).find(" ")+1);

That is, you have to get each lastname out of the whole name before you can compare last names.
So I tried something like this however its still not working, do you possibly spot any errors?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void SortByLastName(vector<string> &students, vector<double> &grades)
{
    cout << "Sorting by last name" << endl;

    int i, j;
    string temp;
    string lastNamej;
    string lastNamei;
    double temp_grade;

    for(i = 0; i < students.size(); ++i)
    {
        lastNamei = students.at(i).substr(students.at(i).find(' ')+1);
        for(j = i + 1; j < students.size()-1; ++j)
        {
            lastNamej = students.at(j).substr(students.at(j).find(' ')+1);
            if (lastNamej < lastNamei)
            {
                temp_grade = grades.at(i);
                grades.at(i) = grades.at(j);
                grades.at(j) = temp_grade;

                temp = lastNamei;
                lastNamei = lastNamej;
                lastNamej = temp;
            }
        }

    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void SortByLastName(vector<string> &students, vector<double> &grades)
{
    for (size_t i = 0; i < students.size(); ++i)
    {
        string lastNamei = students.at(i).substr(students.at(i).find(' ')+1);
        for (size_t j = i + 1; j < students.size(); ++j)
        {
            string lastNamej = students.at(j).substr(students.at(j).find(' ')+1);
            if (lastNamej < lastNamei)
            {
                double temp_grade = grades.at(i);
                grades.at(i) = grades.at(j);
                grades.at(j) = temp_grade;

                string temp = students.at(i);
                students.at(i) = students.at(j);
                students.at(j) = temp;

                lastNamei = lastNamej;
            }
        }
    }
}

Thank you both for your help it worked @dutch, and @salem c, your explanation was helpful. I figured there are much simpler ways to sort through c++
What's with all the .at() ? As the loops are from 0 to < .size(), then using [] is OK as the subscript won't be out of bounds.

Also, there's std::swap() to swap 2 items.
Topic archived. No new replies allowed.