CS253: Software Development with C++

Spring 2018

Sorting With Functors

See this page as a slide show

CS253 Sorting With Functors

Sorting

The Idiot Savant

Comparison functor

Implicit/explicit

Implicit sorting criterion:

set<int> s = {31, 41, 59, 26, 53, 58, 97, 93, 23, 84};
for (auto v : s)
    cout << v << ' ';
23 26 31 41 53 58 59 84 93 97 

Explicit sorting criterion:

set<int, less<int> > s = {31, 41, 59, 26, 53, 58, 97, 93, 23, 84};
for (auto v : s)
    cout << v << ' ';
23 26 31 41 53 58 59 84 93 97 

What’s this > > folderol?

Reversed

Use greater<int> to sort from biggest to smallest:

set<int, greater<int>> s = {31, 41, 59, 26, 53, 58, 97, 93, 23, 84};
for (auto v : s)
    cout << v << ' ';
97 93 84 59 58 53 41 31 26 23 

Explicitly explicit

Use a comparison functor that behaves the same as less<int>:

struct compare {                            // 😱😱struct‽😱😱
    bool operator()(int a, int b) const {
        return a < b;
    }
};

set<int, compare> s = {31, 41, 59, 26, 53, 58, 97, 93, 23, 84};
for (auto v : s)
    cout << v << ' ';
23 26 31 41 53 58 59 84 93 97 

Two-level

Use a comparison functor that does a two-level comparison, like last name/first name.

struct compare {
    bool operator()(int a, int b) const {
        int da = abs(a-50), db = abs(b-50);
        if (da != db)
            return da < db; // Primary sort: distance from 50
        return a < b;       // Secondary sort: value of number
    }
};

set<int, compare> s = {31, 41, 59, 26, 53, 58, 97, 93, 23, 84};
for (auto v : s)
    cout << v << ' ';
53 58 41 59 31 26 23 84 93 97 

Ternary operator

Another way to write a two-level comparison functor:

struct compare {
    bool operator()(int a, int b) const {
        int da = abs(a-50), db = abs(b-50);
        return (da != db) ? da < db : a < b;
    }
};

set<int, compare> s = {31, 41, 59, 26, 53, 58, 97, 93, 23, 84};
for (auto v : s)
    cout << v << ' ';
53 58 41 59 31 26 23 84 93 97 

Curious criteria

This sorts by different criteria:

struct compare {
    bool operator()(int a, int b) const {
        int last_a = a%10, last_b = b%10;
        if (last_a != last_b)
            return last_a < last_b; // Primary sort: by last digit
        return a < b;               // Secondary sort: value of number
    }
};

set<int, compare> s = {31, 41, 59, 26, 53, 58, 97, 93, 23, 84};
for (auto v : s)
    cout << v << ' ';
31 41 23 53 93 84 26 97 58 59 

Multi-level

struct student {
    int id; string name; float gpa;
};
struct compare {
    bool operator()(const student &a, const student &b) const {
        return (a.gpa != b.gpa) ? a.gpa > b.gpa : a.id < b.id;
    }
};
set<student,compare> s = {
    {81234567, "Jack Applin",      3.9},
    {82828282, "Darrell Whitley",  0.5},
    {84444444, "Homecoming Queen", 2.2},
    {83333333, "Joe Kolledge",     2.2},
};
for (const auto &v : s)
    cout << v.id << ' ' << v.gpa << ' ' << v.name << '\n';
81234567 3.9 Jack Applin
83333333 2.2 Joe Kolledge
84444444 2.2 Homecoming Queen
82828282 0.5 Darrell Whitley

Not all

User: Guest

Check: HTML CSS
Edit History Source

Modified: 2018-04-24T16:56

Apply to CSU | Contact CSU | Disclaimer | Equal Opportunity
Colorado State University, Fort Collins, CO 80523 USA
© 2018 Colorado State University
CS Building