Skip to content

Module 08 Solutions

Download Module 08 Solutions

Generic search in containers.

easyfind.hpp
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:

  • typename required for dependent types
  • Throws exception if not found
  • Works with vector, list, deque (not map)

Store N integers and find spans.

Span.hpp
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;
};
Span.cpp
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;
}

Make stack iterable by exposing underlying container.

MutantStack.hpp
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.