CS253 Sorting With Functors
set
know the sorting order?
int
and string
, but what
about class Student
?
int
, you might want to sort in a different order.
set
is like that. It knows the mechanics of sorting,
but it doesn’t know what order to use. You need to help it.
set
with a comparison functor.
set
code makes comparisons using the functor.
true
iff the first item should come
before the second item.
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?
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
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
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
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
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
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}, {87654321, "Darrell Whitley", 0.5}, {83333333, "Homecoming Queen", 2.2}, {84444444, "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 Homecoming Queen 84444444 2.2 Joe Kolledge 87654321 0.5 Darrell Whitley
vector
, array
, and list
just go in the order you specify,
and so have no comparison functor.
unordered_set
needs only an equality comparison (and a hash
functor), so its comparison functor defaults to equal_to
,
not less
.
Modified: 2017-04-12T14:22 User: Guest Check: HTML CSSEdit History Source |
Apply to CSU |
Contact CSU |
Disclaimer |
Equal Opportunity Colorado State University, Fort Collins, CO 80523 USA © 2015 Colorado State University |