Module 08 Solutions
Exercise 00: easyfind
Section titled “Exercise 00: easyfind”Generic search in containers.
template <typename T>typename T::iterator easyfind(T& container, int value) { typename T::iterator it = std::find(container.begin(), container.end(), value); if (it == container.end()) throw std::runtime_error("Value not found"); return it;}Key Points:
typenamerequired for dependent types- Throws exception if not found
- Works with vector, list, deque (not map)
Exercise 01: Span
Section titled “Exercise 01: Span”Store N integers and find spans.
class Span {private: std::vector<int> _numbers; unsigned int _maxSize;
public: Span(unsigned int n);
void addNumber(int n);
// Add range of numbers template <typename Iterator> void addNumber(Iterator begin, Iterator end) { while (begin != end) { addNumber(*begin); ++begin; } }
int shortestSpan() const; int longestSpan() const;};void Span::addNumber(int n) { if (_numbers.size() >= _maxSize) throw std::runtime_error("Span is full"); _numbers.push_back(n);}
int Span::shortestSpan() const { if (_numbers.size() < 2) throw std::runtime_error("Not enough numbers");
std::vector<int> sorted = _numbers; std::sort(sorted.begin(), sorted.end());
int minSpan = sorted[1] - sorted[0]; for (size_t i = 2; i < sorted.size(); i++) { int span = sorted[i] - sorted[i-1]; if (span < minSpan) minSpan = span; } return minSpan;}
int Span::longestSpan() const { if (_numbers.size() < 2) throw std::runtime_error("Not enough numbers");
int min = *std::min_element(_numbers.begin(), _numbers.end()); int max = *std::max_element(_numbers.begin(), _numbers.end()); return max - min;}Exercise 02: MutantStack
Section titled “Exercise 02: MutantStack”Make stack iterable by exposing underlying container.
template <typename T>class MutantStack : public std::stack<T> {public: MutantStack() {} MutantStack(const MutantStack& other) : std::stack<T>(other) {} MutantStack& operator=(const MutantStack& other) { std::stack<T>::operator=(other); return *this; } ~MutantStack() {}
// Expose container's iterator types typedef typename std::stack<T>::container_type::iterator iterator; typedef typename std::stack<T>::container_type::const_iterator const_iterator; typedef typename std::stack<T>::container_type::reverse_iterator reverse_iterator; typedef typename std::stack<T>::container_type::const_reverse_iterator const_reverse_iterator;
iterator begin() { return this->c.begin(); } iterator end() { return this->c.end(); } const_iterator begin() const { return this->c.begin(); } const_iterator end() const { return this->c.end(); } reverse_iterator rbegin() { return this->c.rbegin(); } reverse_iterator rend() { return this->c.rend(); }};Key Insight: std::stack has protected member c (the underlying container, default std::deque). We can expose its iterators.