Lesson 10 of 10
Counting and sorting
- 15 min
- 5 checks
- 3 hints
- Go to task
Goal
Counting with std::map and sorting with std::sort and a lambda
Explanation
A map such as std::map<std::string, int> links each key to a value and always stays sorted by its keys. The line counts[item]++ is all you need to count items, because [] creates a missing key with a value of zero and then increments it. You go through the pairs with for (const auto& [item, n] : counts), which splits each pair into a key and a value. auto works out the type for you, and the pairs come out in key order.
Watch out: [] creates the key even when you're only reading, so if (counts["axe"] > 0) adds "axe" to the map with a value of zero. With a const std::map& the compiler doesn't accept [] at all, so for reading, use count(key), at(key) or a loop over the pairs.
std::sort(v.begin(), v.end()) from <algorithm> sorts the elements in ascending order using <, and for any other order you give it a comparison function. A lambda is a small function you write right where you need it: [](const Player& a, const Player& b) { return a.score > b.score; } returns true when a comes before b. std::sort doesn't guarantee the order of equal elements, so if you want a predictable order, add a second criterion that's used for ties.
Your task
Complete std::map<std::string, int> countLoot(const std::vector<std::string>& drops) so it returns how many times each item of loot appears, and std::string mostCommon(const std::map<std::string, int>& counts) so it returns the most common item, the one that comes first in the map's order when there's a tie, or an empty string if the map is empty. Then complete void sortByScore(std::vector<Player>& players) so it sorts the players in the vector itself from the highest score to the lowest, and alphabetically by name when scores are tied.
Checks
5 checks- countLoot counts each item and returns an empty map for an empty list
- mostCommon returns the most common item
- mostCommon returns the earlier key on a tie and an empty string for an empty map
- sortByScore puts the highest score first
- sortByScore sorts tied players alphabetically by name