1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
#include "stdafx.h"
#include <deque>
#include <iostream>
#include <algorithm>
#include <string>
class Student
{
public:
//constructors
Student(std::string firstName, std::string lastName, std::string hometown, unsigned int id)
: firstName_(firstName), lastName_(lastName), hometown_(hometown), id_(id) {}
Student() : firstName_(""), lastName_(""), hometown_(""), id_(0) {}
//destructor
~Student() {}
// accessor functions
std::string getHometown() const { return hometown_; }
std::string getFirstName() const { return firstName_; }
std::string getLastName() const { return lastName_; }
unsigned int getId() const { return id_; };
// mutator functions.
void addSubject(const std::string& subject) { classes_.push_back(subject); }
void setFirstName(std::string& name) { firstName_ = name; }
void setlastName(std::string& name) { lastName_ = name; }
void setHometown(std::string& name) { hometown_ = name; }
void setId(std::string& name) { firstName_ = name; }
// overloaded << so that we can output directly to a stream
friend std::ostream& operator<<(std::ostream& os, const Student& s)
{
return os << s.getFirstName() << "\t\t" << s.getLastName() << "\t\t"
<< s.getHometown() << "\t" << s.getId();
}
// This is an overloaded relational operator. It is needed to allow arrays of
// Student objects to be sorted using std::sort. This is called during the
// operation so that each object in the array can be compared against one another.
bool operator<(const Student& rhs)
{
return (id_ < rhs.id_);
}
// declare friends
friend struct PrintSubjects;
friend struct IsTakingCalculus;
private:
std::string firstName_;
std::string lastName_;
std::string hometown_;
unsigned int id_;
std::deque<std::string> classes_;
};
// printing functor for use with std::foreach. It works because operator<< is overloaded
// for the student class.
struct SendToStream
{
void operator() (const Student& s) { std::cout << s << std::endl; }
} StsFtr;
struct PrintSubjects
{
void operator() (const Student& s)
{
std::cout << "\n" << s << "\n";
std::deque<std::string>::const_iterator pos = s.classes_.begin();
for(; pos < s.classes_.end(); ++pos)
{
std::cout << *pos << " "; // 3 spaces
}
std::cout << "\n";
}
} PsFtr;
// used with count_if to count the number of students from san diego.
struct IsFromSanDiego
{
bool operator() (const Student& s) { return (s.getHometown() == "San Diego, CA"); }
} IfSdFtr;
// used with count_if to count the number of students taking calculus
struct IsTakingCalculus
{
bool operator() (const Student& s)
{
return (std::find(s.classes_.begin(), s.classes_.end(), "calculus") != s.classes_.end());
}
} ItcFtr;
typedef std::deque<Student> Students;
int main()
{
//Build an array of students.
Students theStudents;
// construct 10 students
theStudents.push_back(Student("Sandra", "Fox", "San Diego, CA", 12111));
theStudents.push_back(Student("Warren", "Pierce", "Fairbanks, AK", 12112));
theStudents.push_back(Student("Dan", "Wright", "St. Louis, MO", 12113));
theStudents.push_back(Student("Amelia", "Timlin", "Erie, PA", 24312));
theStudents.push_back(Student("Anne", "Bradley", "Boston, MA", 24315));
theStudents.push_back(Student("Mike", "Harding", "San Diego, CA", 24316));
theStudents.push_back(Student("Sandra", "Brown", "Boston, MA", 38125));
theStudents.push_back(Student("Melissa", "Turner", "Boston, MA", 38126));
theStudents.push_back(Student("Jack", "Turner", "San Diego, CA", 12114));
theStudents.push_back(Student("Sandra", "Rice", "St. Louis, MO", 24317));
// print students in the original order
std::cout << "\nPrint the students in the original order. " << std::endl;
std::for_each(theStudents.begin(), theStudents.end(), StsFtr);
// Use std algorithms to collect and display student metrics.
Students::iterator pos;
// print the student with the largest student id
std::cout << "\nPrint the student with the largest id. " << std::endl;
if( (pos = std::max_element(theStudents.begin(), theStudents.end())) != theStudents.end())
StsFtr(*pos);
// print the student with the smallest student id
std::cout << "\nPrint the student with the smallest id. " << std::endl;
if( (pos = std::min_element(theStudents.begin(), theStudents.end())) != theStudents.end())
StsFtr(*pos);
// sort the students by student id. The operator< for the student uses the id so
// we don't need to use a functor.
std::cout << "\nSort the student by their student id. " << std::endl;
std::sort(theStudents.begin(), theStudents.end());
std::for_each(theStudents.begin(), theStudents.end(), StsFtr);
// reverse the order
std::cout << "\nReverse the order of elements within the container" << std::endl;
std::reverse(theStudents.begin(), theStudents.end());
std::for_each(theStudents.begin(), theStudents.end(), StsFtr);
// shuffle the array into a random order
std::cout << "\nShuffle the container " << std::endl;
std::random_shuffle(theStudents.begin(), theStudents.end());
std::for_each(theStudents.begin(), theStudents.end(), StsFtr);
// add some subjects to the student classes
std::string subjectsArray[7] = { "calculus", "physics", "philosophy", "history", "biology", "grammar", "spanish" };
for(pos = theStudents.begin(); pos < theStudents.end(); ++pos)
{
// add three random subjects to each student object
pos->addSubject(subjectsArray[1]);
pos->addSubject(subjectsArray[3]);
pos->addSubject(subjectsArray[5]);
std::random_shuffle(subjectsArray, subjectsArray + 5);
}
std::for_each(theStudents.begin(), theStudents.end(), PsFtr);
// Try using find and count functions using a predicate that searches for subjects contained
// in student objects.
std::cout << std::count_if(theStudents.begin(), theStudents.end(), ItcFtr)
<< " are taking calculus.\n";
std::cout << std::count_if(theStudents.begin(), theStudents.end(), IfSdFtr)
<< " are from San Diego, CA.\n";
return 0;
}
|