Need to sort multiple arrays

I've got a program where a user will enter a student's name and numerical grade.

The program will then determine the letter grade based on the numerical grade.

I currently have 4 arrays setup. First name, last name, numerical grade and letter grade.

I need to be able to sort all of this information by numerical grade from lowest to highest.

So far, I've only been able to get it to sort the numerical grade, but obviously the other information no longer lines up properly.

Any suggestions would be appreciated.

Thank you.

Jason
I suggest you having all the information variables in a class so you can have just one array.
To sort it, you would have to overload the < operator for that class
Last edited on
Take a look at this. I had created this example using a student class since I know that a lot of beginners or students are working on exercises like this. It shows you how to use a few of the simpler algorithms as well as functors that can be used to amplify the behavior of an algorithm.
http://cplusplus.com/forum/articles/10879/

In that example, I implemented operator< to sort objects by the student id. However you could get creative and do one of two things.
A) You could write a functor for each sorting criteria. Write one that compares the grade, one that compares the last name, etc. When you call std::sort you specify the appropriate functor based on how you wish to sort.
B) Another way that I had though of doing it is to create a static member function that allows you to specify a constant used for determining the sort criteria. Then your operator < could check that constant in a switch and choose the case based on a set of related constants (AGE, LAST_NAME, FIRST_NAME, GPA, and so forth).

In other words, I agree with Bazzy. you are better off creating a data structure or class for your student records. Then you just have one array to deal with.
Ok, I've created a data structure so everything is going into one array, but I'm still unclear on how to sort it based on one of the variables (the student's score in this case).

Thanks.

Jason
Here is the code as I have it now, with no sorting.

Thanks.

Jason

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
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <cmath>

using namespace std;

struct studentGrade {
  string fName;
  string lName;
  string letter;
  int grade;
} student[24];

int main () {

  int count = 0, gTemp;
  double avg, sqAvg, total, sqTotal, sqTotalAvg, stdDev;
  string fTemp, lTemp, input;
  bool anotherStudent = true;

  cout << "Enter up to 25 student names and their numerical grade, 0 - 100" << endl;
  cout << "Enter 'quit' when you are finished entering data. " << endl;

  do  {
    cout << "\nEnter the first name of student #" << count + 1 << ": ";
    cin >> fTemp;

    if (fTemp == "quit") {
      anotherStudent = false;
      continue;
    }

    else {
      cout << "\nEnter the last name of student #" << count + 1 << ": ";
      cin >> lTemp;

      cout << "\nEnter student #" << count +1 << "'s numerical grade: ";
      cin >> input;
      istringstream iss(input);
      iss >> gTemp;

        if ((iss && gTemp >= 0) || (iss && gTemp <= 100)) {
          fTemp[0] = toupper( fTemp[0] );
          lTemp[0] = toupper( lTemp[0] );
          student[count].fName = fTemp;
          student[count].lName = lTemp;
          student[count].grade = gTemp;
          total += gTemp;
        }

        else {
          cout << "You have entered an invalid grade. " << endl;
          gTemp = 0;
          continue;
        }
     }

  if (gTemp >= 0 && gTemp <= 59) {
    student[count++].letter = "F";
  }

  else if (gTemp >= 60 && gTemp <= 69) {
    student[count++].letter = "C";
  }

  else if (gTemp >= 70 && gTemp <= 74) {
    student[count++].letter = "C+";
  }

  else if (gTemp >= 75 && gTemp <= 79) {
    student[count++].letter = "B-";
  }

  else if (gTemp >= 80 && gTemp <= 84) {
    student[count++].letter = "B";
  }

  else if (gTemp >= 85 && gTemp <= 89) {
    student[count++].letter = "B+";
  }

  else if (gTemp >= 90 && gTemp <= 94) {
    student[count].letter = "A-";
  }

  else if (gTemp >= 95 && gTemp <= 100) {
    student[count++].letter = "A";
  }

  } while(anotherStudent && count <= 24);


  if (count > 1) {
    avg = (total / count);

    for (int i = 0; i < count; i++) {
      sqTotal += pow( (avg - student[i].grade), 2.0 );
    }

    sqTotalAvg = (sqTotal / count);

    stdDev = sqrt(sqTotalAvg);
    cout << fixed;
    cout << "\n" << count << " exam scores have been entered. " << endl;
    cout << "\nThe average score is " << avg << endl;
    cout << "\nThe standard deviation of the entered scores is "<< stdDev << endl << endl;
  }

  for (int i = 0; i < count; i++) {
  cout << "Name: " << student[i].fName <<" " << student[i].lName;
  cout << " - Score: " << student[i].grade << " - Grade: ";
  cout << student[i].letter << endl;
  }
}
Create functions which return whether the first argument comes before the second and use them as comparison functions for sort std algorithm
eg:
1
2
3
4
5
6
7
8
9
10
11
12
#include <algorithm>

//...

bool by_grade ( const studentGrade &a, const studentGrade &b )
{
    return a.grade < b.grade;
}

//...

sort( student, student+24, by_grade ); // 24 is the size of the array 


http://www.cplusplus.com/reference/algorithm/sort/
Last edited on
I am guessing that you have to write your own sort function (like a bubble sort).
If that's the case, then you should already know the algorithm. Bubble sort
compares two elements. In your case, they are studentGrade structs. You
should compare only the "grade" member of the two structs. This will have
the effect of sorting by grade. ie, if( student[idx].grade < student[idx+1].grade )

If you are allowed to use std::sort(), then the problem is much easier, in
which case you can do as kempofighter suggested (write operator< for
studentGrade).

NB: you can still write operator< for studentGrade if you have to write
your own sort routine. In which case your if() would be
if( student[idx] < student[idx+1] ), which will call operator< on
studentGrade.

And there are still other, even shorter ways to do it, but they require
boost::lambda or boost::multi_index_container.

EDIT: Ok, so I can't resist.

1
2
3
std::sort( student, student + count,
  &boost::lambda::_1->*&studentGrade::grade <
  &boost::lambda::_2->*&studentGrade::grade );


And the whole thing is sorted by grade.
Last edited on
Thank you, thank you, thank you.

Specifically Bazzy and Kempofighter.

Through a combination of your posts I was able to get my program working correctly.

I am very happy.

Thanks again everyone.

Jason
Topic archived. No new replies allowed.