// Build and maintain a list of students enrolled in a class and the waiting list.
#include
#include
#include
#include
#include
using namespace std;
void enroll_student(const string& id_number, unsigned int max_students,
vector& enrolled, vector& waiting);
void remove_student(const string& id_number, unsigned int max_students,
vector& enrolled, vector& waiting);
void erase_from_vector(vector::iterator itr, vector& v);
int main() {
// Read in the maximum number of students in the course
unsigned int max_students;
cout << "\nWelcome to the enrollment program for CSCI 1200\n"
<< "Please enter the maximum number of students allowed\n";
cin >> max_students;
// Initialize the vector
vector enrolled;
vector waiting;
// Invariant:
// (1) enrolled contains the students already in the course,
// (2) waiting contains students who would will to be admitted (in
// the order of request) if a spot opens up, in the
// (3) enrolled.size() <= max_students,
// (4) if the course is not filled (enrolled.size() != max_students)
// then waiting is empty
do {
// check (part of) the invariant
assert (enrolled.size() <= max_students);
assert (enrolled.size() == max_students || waiting.size() == 0);
cout << "\nOptions:\n"
<< " To enroll a student type 0\n"
<< " To remove a student type 1\n"
<< " To end type 2\n"
<< "Type option ==> ";
int option;
if (!(cin >> option)) { // if we can't read the input integer, then just fail.
cout << "Illegal input. Good-bye.\n";
return 1;
} else if (option == 2) {
break; // quit by breaking out of the loop.
} else if (option != 0 && option != 1) {
cout << "Invalid option. Try again.\n";
} else { // option is 0 or 1
string id_number;
cout << "Enter student id: ";
if (!(cin >> id_number)) {
cout << "Illegal input. Good-bye.\n";
return 1;
} else if (option == 0) {
enroll_student(id_number, max_students, enrolled, waiting);
} else {
remove_student(id_number, max_students, enrolled, waiting);
}
}
}
while (true);
// some nice output
sort(enrolled.begin(), enrolled.end());
cout << "\nAt the end of the enrollment period, the following students\n"
<< "are in the class:\n\n";
for (vector::iterator i=enrolled.begin(); i != enrolled.end(); i++) {
cout << *i << endl;
}
if (!waiting.empty()) {
cout << "\nStudents are on the waiting list in the following order:\n";
for (vector::iterator j=waiting.begin(); j != waiting.end(); j++) {
cout << *j << endl;
}
}
return 0;
}
// Enroll a student in the course if there is room and if the student
// is not already in the course or on the waiting list.
void enroll_student(const string& id_number, unsigned int max_students,
vector& enrolled, vector& waiting) {
// Check to see if the student is already enrolled.
unsigned int i;
for (vector::iterator i=enrolled.begin(); i != enrolled.end(); i++) {
if (*i == id_number) {
cout << "Student " << id_number << " is already enrolled." << endl;
return;
}
}
// If the course isn't full, add the student.
if (enrolled.size() < max_students) {
enrolled.push_back(id_number);
cout << "Student " << id_number << " added.\n" << enrolled.size()
<< " students are now in the course." << endl;
return;
}
// Check to see if the student is already on the waiting list.
for (vector::iterator j=waiting.begin(); j != waiting.end(); j++) {
if (*j == id_number) {
cout << "Student " << id_number << " is already on the waiting list." << endl;
return;
}
}
// If not, add the student to the waiting list.
waiting.push_back(id_number);
cout << "The course is full. Student " << id_number
<< " has been added to the waiting list.\n" << waiting.size()
<< " students are on the waiting list." << endl;
}
// Remove a student from the course or from the waiting list. If
// removing the student from the course opens up a slot, then the
// first person on the waiting list is placed in the course.
void remove_student(const string& id_number, unsigned int max_students,
vector& enrolled, vector& waiting) {
// Check to see if the student is on the course list.
bool found = false;
vector::iterator itr = enrolled.begin();
while (!found && itr != enrolled.end()) {
found = *itr == id_number;
if (!found) itr++;
}
if (found) {
// Remove the student and see if a student can be taken from the waiting list.
erase_from_vector(itr, enrolled);
cout << "Student " << id_number << " removed from the course." << endl;
if (waiting.size() > 0) {
enrolled.push_back(*waiting.begin());
cout << "Student " << *waiting.begin() << " added to the course "
<< "from the waiting list." << endl;
erase_from_vector(waiting.begin(), waiting);
cout << waiting.size() << " students remain on the waiting list." << endl;
} else {
cout << enrolled.size() << " students are now in the course." << endl;
}
} else {
// Check to see if the student is on the waiting list
found = false;
vector::iterator wait_itr = waiting.begin();
while (!found && wait_itr != waiting.end()) {
found = *wait_itr == id_number;
if (!found) ++wait_itr;
}
if (found) {
erase_from_vector(wait_itr, waiting);
cout << "Student " << id_number << " removed from the waiting list.\n"
<< waiting.size() << " students remain on the waiting list." << endl;
} else {
cout << "Student " << id_number << " is in neither the course nor the waiting list" << endl;
}
}
}
// Remove the value at index location i from a vector of strings. The
// size of the vector should be reduced by one when the function is finished.
void erase_from_vector(vector::iterator itr, vector& v) {
assert (itr >= v.begin());
assert (v.size() > 0);
assert (itr < v.end());
int old_size = v.size();
// shift everything forward
vector::iterator itr2 = itr;
itr2++;
while (itr2 != v.end()) {
*itr = *itr2;
itr++;
itr2++;
}
// shorten the vector by 1
v.pop_back();
assert (v.size() == old_size - 1);
}