C++: A grade book with a map of vectors

Combine two containers: a map from names to vectors of marks.

What to build

A grade book that groups marks by student and reports on each one.

Requirements

  • Store the marks in a map<string, vector<int>>.
  • For each student, in name order, print the number of marks, the average with two decimals, and the best mark.
  • Finally print the student with the highest average. If several share it, print the first in name order.

Input

The first line has n. Each of the next n lines has a name and a mark.

Output

One line per student, NAME count C avg A best B, then top NAME.

Constraints

1 ≤ n ≤ 1000, names are one word, and marks are from 0 to 100.

Example

Input:

5
Rahim 70
Asha 90
Rahim 80
Chen 85
Asha 70

Output:

Asha count 2 avg 80.00 best 90
Chen count 1 avg 85.00 best 85
Rahim count 2 avg 75.00 best 80
top Chen

Why it works

The map keeps names sorted and creates an empty vector the first time a name appears. Walking it in order and replacing the top only on a strictly higher average gives the first name in order on a tie.

Examples

Example 1 · Input
5
Rahim 70
Asha 90
Rahim 80
Chen 85
Asha 70
Expected output
Asha count 2 avg 80.00 best 90
Chen count 1 avg 85.00 best 85
Rahim count 2 avg 75.00 best 80
top Chen
Example 2 · Input
1
Solo 50
Expected output
Solo count 1 avg 50.00 best 50
top Solo

Hints

Hint 1

`map<string, vector<int>> marks;` and `marks[name].push_back(mark);` group the marks by student, with names kept in order.

Hint 2

For each student, work out the count, the average and the best mark from their vector.

Hint 3

To find the top student, keep the best average so far and replace it only when a later average is strictly higher.

Solution

Show one correct solution (try it yourself first)
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <iomanip>
using namespace std;

int main() {
    int n;
    cin >> n;
    map<string, vector<int>> marks;
    for (int i = 0; i < n; i++) {
        string name;
        int mark;
        cin >> name >> mark;
        marks[name].push_back(mark);
    }
    cout << fixed << setprecision(2);
    string top = "";
    double topAverage = -1;
    for (auto& p : marks) {
        int sum = 0, best = 0;
        for (int m : p.second) {
            sum += m;
            if (m > best) best = m;
        }
        double average = (double)sum / p.second.size();
        cout << p.first << " count " << p.second.size() << " avg " << average << " best " << best << endl;
        if (average > topAverage) {
            topAverage = average;
            top = p.first;
        }
    }
    cout << "top " << top << endl;
    return 0;
}

Lesson: The standard library: vector, string, map and sort →