Task: Top rank per group
C: #include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    const char *name, *id, *dept;
    int sal;
} person;

person ppl[] = {
    {"Tyler Bennett",   "E10297", "D101", 32000},
    {"John Rappl",      "E21437", "D050", 47000},
    {"George Woltman",  "E00127", "D101", 53500},
    {"Adam Smith",      "E63535", "D202", 18000},
    {"Claire Buckman",  "E39876", "D202", 27800},
    {"David McClellan", "E04242", "D101", 41500},
    {"Rich Holcomb",    "E01234", "D202", 49500},
    {"Nathan Adams",    "E41298", "D050", 21900},
    {"Richard Potter",  "E43128", "D101", 15900},
    {"David Motsinger", "E27002", "D202", 19250},
    {"Tim Sampair",     "E03033", "D101", 27000},
    {"Kim Arlich",      "E10001", "D190", 57000},
    {"Timothy Grove",   "E16398", "D190", 29900},
};

int pcmp(const void *a, const void *b)
{
    const person *aa = a, *bb = b;
    int x = strcmp(aa->dept, bb->dept);
    if (x) return x;
    return aa->sal > bb->sal ? -1 : aa->sal < bb->sal;
}

#define N sizeof(ppl)/sizeof(person)
void top(int n)
{
    int i, rank;
    qsort(ppl, N, sizeof(person), pcmp);

    for (i = rank = 0; i < N; i++) {
        if (i && strcmp(ppl[i].dept, ppl[i - 1].dept)) {
            rank = 0;
            printf("\n");
        }

        if (rank++ < n)
            printf("%s %d: %s\n", ppl[i].dept, ppl[i].sal, ppl[i].name);
    }
}

int main()
{
    top(2);
    return 0;
}

C++: #include <string>
#include <set>
#include <list>
#include <map>
#include <iostream>


struct Employee
{
    std::string Name;
    std::string ID;
    unsigned long Salary;
    std::string Department;
    Employee(std::string _Name = "", std::string _ID = "", unsigned long _Salary = 0, std::string _Department = "")
    : Name(_Name), ID(_ID), Salary(_Salary), Department(_Department)
    { }

    void display(std::ostream& out) const
    {
        out << Name << "\t" << ID << "\t" << Salary << "\t" << Department << std::endl;
    }
};


struct CompareEarners
{
    bool operator()(const Employee& e1, const Employee& e2)
    {
        return (e1.Salary > e2.Salary);
    }
};


typedef std::list<Employee> EMPLOYEELIST;



typedef std::set<Employee, CompareEarners> DEPARTMENTPAYROLL;

typedef std::map<std::string, DEPARTMENTPAYROLL> DEPARTMENTLIST;

void initialize(EMPLOYEELIST& Employees)
{
    
    Employees.push_back(Employee("Tyler Bennett", "E10297", 32000, "D101"));
    Employees.push_back(Employee("John Rappl", "E21437", 47000, "D050"));
    Employees.push_back(Employee("George Woltman", "E21437", 53500, "D101"));
    Employees.push_back(Employee("Adam Smith", "E21437", 18000, "D202"));
    Employees.push_back(Employee("Claire Buckman", "E39876", 27800, "D202"));
    Employees.push_back(Employee("David McClellan", "E04242", 41500, "D101"));
    Employees.push_back(Employee("Rich Holcomb", "E01234", 49500, "D202"));
    Employees.push_back(Employee("Nathan Adams", "E41298", 21900, "D050"));
    Employees.push_back(Employee("Richard Potter", "E43128", 15900, "D101"));
    Employees.push_back(Employee("David Motsinger", "E27002", 19250, "D202"));
    Employees.push_back(Employee("Tim Sampair", "E03033", 27000, "D101"));
    Employees.push_back(Employee("Kim Arlich", "E10001", 57000, "D190"));
    Employees.push_back(Employee("Timothy Grove", "E16398", 29900, "D190"));
}

void group(EMPLOYEELIST& Employees, DEPARTMENTLIST& Departments)
{
    
    for( EMPLOYEELIST::iterator iEmployee = Employees.begin();
         Employees.end() != iEmployee;
         ++iEmployee )
    {
        DEPARTMENTPAYROLL& groupSet = Departments[iEmployee->Department];

        
        groupSet.insert(*iEmployee);
    }
}

void present(DEPARTMENTLIST& Departments, unsigned int N)
{
    
    for( DEPARTMENTLIST::iterator iDepartment = Departments.begin();
         Departments.end() != iDepartment;
         ++iDepartment )
    {
        std::cout << "In department " << iDepartment->first << std::endl;
        std::cout << "Name\t\tID\tSalary\tDepartment" << std::endl;
        
        unsigned int rank = 1;
        for( DEPARTMENTPAYROLL::iterator iEmployee = iDepartment->second.begin();
             ( iDepartment->second.end() != iEmployee) && (rank <= N);
             ++iEmployee, ++rank )
        {
            iEmployee->display(std::cout);
        }
        std::cout << std::endl;
    }
}

int main(int argc, char* argv[])
{
    
    EMPLOYEELIST Employees;

    
    initialize(Employees);

    
    DEPARTMENTLIST Departments;

    
    
    group(Employees, Departments);

    
    present(Departments, 3);

    return 0;
}