Welcome to today's lesson! We'll be exploring a practical application of C++ sets by managing student enrollments for various courses. Imagine you're running an online course platform and need to handle enrollments, checks, and listings of students in different courses. std::unordered_set
would be perfect for this kind of problem since it does not allow duplicates, ensuring that a student can't enroll in the same course more than once!
By the end of this session, you'll be well-versed in using sets for such tasks. Let’s dive in!
Here are the methods we need to implement in our enrollment system:
void enroll(const std::string& student, const std::string& course);
: This method adds a student to a course. If the student is already enrolled, it does nothing.bool unenroll(const std::string& student, const std::string& course);
: This method removes a student from a course. It returnstrue
if the student was enrolled and has now been removed. Otherwise, it returnsfalse
. If after unenrolling the student, the course becomes empty (no one is enrolled there), remove the course as well.bool is_enrolled(const std::string& student, const std::string& course);
: This method checks if a student is enrolled in a course. It returnstrue
if the student is enrolled andfalse
otherwise.std::vector<std::string> list_students(const std::string& course);
: This method returns a list of all students enrolled in a given course. If no students are enrolled, it returns an empty vector.
Let's look at how to implement each of these methods step-by-step.
We'll start by defining our class and then add each method one by one.
First, we define our EnrollmentSystem
class:
C++1#include <unordered_map> 2#include <unordered_set> 3#include <string> 4#include <vector> 5 6class EnrollmentSystem { 7public: 8 EnrollmentSystem() = default; 9 10private: 11 std::unordered_map<std::string, std::unordered_set<std::string>> enrollments; 12};
This code initializes an EnrollmentSystem
class with an unordered map named enrollments
that maps courses to unordered sets of students.
Next, we implement the enroll
method:
C++1#include <unordered_map> 2#include <unordered_set> 3#include <string> 4#include <vector> 5#include <iostream> 6 7class EnrollmentSystem { 8public: 9 EnrollmentSystem() = default; 10 11 void enroll(const std::string& student, const std::string& course) { 12 enrollments[course].insert(student); 13 } 14 15private: 16 std::unordered_map<std::string, std::unordered_set<std::string>> enrollments; 17}; 18 19// Example usage: 20int main() { 21 EnrollmentSystem es; 22 es.enroll("Alice", "Math101"); 23 return 0; 24}
Here, the enroll
method uses the insert
method to add the student
to the set of students for the specified course.
Let's move on to the unenroll
method:
C++1#include <unordered_map> 2#include <unordered_set> 3#include <string> 4#include <vector> 5#include <iostream> 6 7class EnrollmentSystem { 8public: 9 EnrollmentSystem() = default; 10 11 void enroll(const std::string& student, const std::string& course) { 12 enrollments[course].insert(student); 13 } 14 15 bool unenroll(const std::string& student, const std::string& course) { 16 auto it = enrollments.find(course); 17 if (it != enrollments.end() && it->second.erase(student) > 0) { 18 if (it->second.empty()) { 19 enrollments.erase(it); 20 } 21 return true; 22 } 23 return false; 24 } 25 26private: 27 std::unordered_map<std::string, std::unordered_set<std::string>> enrollments; 28}; 29 30// Example usage: 31int main() { 32 EnrollmentSystem es; 33 es.enroll("Alice", "Math101"); 34 es.enroll("Bob", "Math101"); 35 es.unenroll("Alice", "Math101"); 36 es.unenroll("Bob", "Math101"); 37 return 0; 38}
This method first checks whether the course
and student
exist in the enrollments. If they do, it removes the student from the course. If the course set becomes empty after removal, it deletes the course from the map. The method returns true
if the student was successfully unenrolled and false
otherwise.
Next, let's implement the is_enrolled
method:
C++1#include <unordered_map> 2#include <unordered_set> 3#include <string> 4#include <vector> 5#include <iostream> 6 7class EnrollmentSystem { 8public: 9 EnrollmentSystem() = default; 10 11 void enroll(const std::string& student, const std::string& course) { 12 enrollments[course].insert(student); 13 } 14 15 bool unenroll(const std::string& student, const std::string& course) { 16 auto it = enrollments.find(course); 17 if (it != enrollments.end() && it->second.erase(student) > 0) { 18 if (it->second.empty()) { 19 enrollments.erase(it); 20 } 21 return true; 22 } 23 return false; 24 } 25 26 bool is_enrolled(const std::string& student, const std::string& course) const { 27 auto it = enrollments.find(course); 28 return it != enrollments.end() && it->second.find(student) != it->second.end(); 29 } 30 31private: 32 std::unordered_map<std::string, std::unordered_set<std::string>> enrollments; 33}; 34 35// Example usage: 36int main() { 37 EnrollmentSystem es; 38 es.enroll("Alice", "Math101"); 39 std::cout << std::boolalpha << es.is_enrolled("Alice", "Math101") << std::endl; // Output: true 40 std::cout << std::boolalpha << es.is_enrolled("Bob", "Math101") << std::endl; // Output: false 41 return 0; 42}
This method checks whether both the course and the student exist in the enrollments map, returning true
if they do and false
otherwise.
Finally, let's implement the list_students
method:
C++1#include <unordered_map> 2#include <unordered_set> 3#include <string> 4#include <vector> 5#include <iostream> 6 7class EnrollmentSystem { 8public: 9 EnrollmentSystem() = default; 10 11 void enroll(const std::string& student, const std::string& course) { 12 enrollments[course].insert(student); 13 } 14 15 bool unenroll(const std::string& student, const std::string& course) { 16 auto it = enrollments.find(course); 17 if (it != enrollments.end() && it->second.erase(student) > 0) { 18 if (it->second.empty()) { 19 enrollments.erase(it); 20 } 21 return true; 22 } 23 return false; 24 } 25 26 bool is_enrolled(const std::string& student, const std::string& course) const { 27 auto it = enrollments.find(course); 28 return it != enrollments.end() && it->second.find(student) != it->second.end(); 29 } 30 31 std::vector<std::string> list_students(const std::string& course) const { 32 auto it = enrollments.find(course); 33 if (it != enrollments.end()) { 34 return std::vector<std::string>(it->second.begin(), it->second.end()); 35 } 36 return {}; 37 } 38 39private: 40 std::unordered_map<std::string, std::unordered_set<std::string>> enrollments; 41}; 42 43// Example usage: 44int main() { 45 EnrollmentSystem es; 46 es.enroll("Alice", "Math101"); 47 es.enroll("Bob", "Math101"); 48 for (const auto& student : es.list_students("Math101")) { 49 std::cout << student << " "; 50 } 51 // Output: Alice Bob (order may vary as it's an unordered_set) 52 return 0; 53}
This method returns a vector of students enrolled in the given course. If the course is not in the enrollments
map, it returns an empty vector.
In today's lesson, we learned how to manage student enrollments using C++ unordered sets and maps. We implemented methods to enroll and unenroll students, check enrollments, and list students in a course. This task provided a practical way to reinforce your understanding of sets and maps in C++.
I encourage you to move on to the practice to undertake similar challenges to deepen your understanding. Keep experimenting and honing your skills. Happy coding!