set;
* --------------------------
* Creates an empty set of the specified element type.
*/
Set();
/*
* Destructor: ~Set
* ----------------
* Frees any heap storage associated with this set.
*/
virtual ~Set();
/*
* Method: size
* Usage: count = set.size();
* --------------------------
* Returns the number of elements in this set.
*/
int size() const;
/*
* Method: isEmpty
* Usage: if (set.isEmpty()) ...
* -----------------------------
* Returns true
if this set contains no elements.
*/
bool isEmpty() const;
/*
* Method: add
* Usage: set.add(value);
* ----------------------
* Adds an element to this set, if it was not already there. For
* compatibility with the STL set
class, this method
* is also exported as insert
.
*/
void add(const ValueType & value);
void insert(const ValueType & value);
/*
* Method: remove
* Usage: set.remove(value);
* -------------------------
* Removes an element from this set. If the value was not
* contained in the set, no error is generated and the set
* remains unchanged.
*/
void remove(const ValueType & value);
/*
* Method: contains
* Usage: if (set.contains(value)) ...
* -----------------------------------
* Returns true
if the specified value is in this set.
*/
bool contains(const ValueType & value) const;
/*
* Method: isSubsetOf
* Usage: if (set.isSubsetOf(set2)) ...
* ------------------------------------
* Implements the subset relation on sets. It returns
* true
if every element of this set is
* contained in set2
.
*/
bool isSubsetOf(const Set & set2) const;
/*
* Method: clear
* Usage: set.clear();
* -------------------
* Removes all elements from this set.
*/
void clear();
/*
* Operator: ==
* Usage: set1 == set2
* -------------------
* Returns true
if set1
and set2
* contain the same elements.
*/
bool operator==(const Set & set2) const;
/*
* Operator: !=
* Usage: set1 != set2
* -------------------
* Returns true
if set1
and set2
* are different.
*/
bool operator!=(const Set & set2) const;
/*
* Operator: +
* Usage: set1 + set2
* set1 + element
* ---------------------
* Returns the union of sets set1
and set2
, which
* is the set of elements that appear in at least one of the two sets. The
* right hand set can be replaced by an element of the value type, in which
* case the operator returns a new set formed by adding that element.
*/
Set operator+(const Set & set2) const;
Set operator+(const ValueType & element) const;
/*
* Operator: *
* Usage: set1 * set2
* ------------------
* Returns the intersection of sets set1
and set2
,
* which is the set of all elements that appear in both.
*/
Set operator*(const Set & set2) const;
/*
* Operator: -
* Usage: set1 - set2
* set1 - element
* ---------------------
* Returns the difference of sets set1
and set2
,
* which is all of the elements that appear in set1
but
* not set2
. The right hand set can be replaced by an
* element of the value type, in which case the operator returns a new
* set formed by removing that element.
*/
Set operator-(const Set & set2) const;
Set operator-(const ValueType & element) const;
/*
* Operator: +=
* Usage: set1 += set2;
* set1 += value;
* ---------------------
* Adds all of the elements from set2
(or the single
* specified value) to set1
. As a convenience, the
* Set
package also overloads the comma operator so
* that it is possible to initialize a set like this:
*
*
* Set digits;
* digits += 0, 1, 2, 3, 4, 5, 6, 7, 8, 9;
*
*/
Set & operator+=(const Set & set2);
Set & operator+=(const ValueType & value);
/*
* Operator: *=
* Usage: set1 *= set2;
* --------------------
* Removes any elements from set1
that are not present in
* set2
.
*/
Set & operator*=(const Set & set2);
/*
* Operator: -=
* Usage: set1 -= set2;
* set1 -= value;
* ---------------------
* Removes the elements from set2
(or the single
* specified value) from set1
. As a convenience, the
* Set
package also overloads the comma operator so
* that it is possible to remove multiple elements from a set
* like this:
*
*
* digits -= 0, 2, 4, 6, 8;
*
*
* which removes the values 0, 2, 4, 6, and 8 from the set
* digits
.
*/
Set & operator-=(const Set & set2);
Set & operator-=(const ValueType & value);
/*
* Method: first
* Usage: ValueType value = set.first();
* -------------------------------------
* Returns the first value in the set in the order established by the
* foreach
macro. If the set is empty, first
* generates an error.
*/
ValueType first() const;
/*
* Method: toString
* Usage: string str = set.toString();
* -----------------------------------
* Converts the set to a printable string representation.
*/
std::string toString();
/*
* Method: mapAll
* Usage: set.mapAll(fn);
* ----------------------
* Iterates through the elements of the set and calls fn(value)
* for each one. The values are processed in ascending order, as defined
* by the comparison function.
*/
void mapAll(void (*fn)(ValueType)) const;
void mapAll(void (*fn)(const ValueType &)) const;
template
void mapAll(FunctorType fn) const;
/*
* Additional Set operations
* -------------------------
* In addition to the methods listed in this interface, the Set class
* supports the following operations:
*
* - Stream I/O using the << and >> operators
* - Deep copying for the copy constructor and assignment operator
* - Iteration using the range-based for statement and STL iterators
*
* The iteration forms process the Set in ascending order.
*/
/* Private section */
/**********************************************************************/
/* Note: Everything below this point in the file is logically part */
/* of the implementation and should not be of interest to clients. */
/**********************************************************************/
private:
Map map; /* Map used to store the element */
bool removeFlag; /* Flag to differentiate += and -= */
public:
/*
* Hidden features
* ---------------
* The remainder of this file consists of the code required to
* support the comma operator, deep copying, and iteration.
* Including these methods in the public interface would make
* that interface more difficult to understand for the average client.
*/
/* Extended constructors */
template
explicit Set(CompareType cmp) : map(Map(cmp)) {
/* Empty */
}
Set & operator,(const ValueType & value) {
if (this->removeFlag) {
this->remove(value);
} else {
this->add(value);
}
return *this;
}
/*
* Iterator support
* ----------------
* The classes in the StanfordCPPLib collection implement input
* iterators so that they work symmetrically with respect to the
* corresponding STL classes.
*/
class iterator : public std::iterator {
private:
typename Map::iterator mapit; /* Iterator for the map */
public:
iterator() {
/* Empty */
}
iterator(typename Map::iterator it) : mapit(it) {
/* Empty */
}
iterator(const iterator & it) {
mapit = it.mapit;
}
iterator & operator=(const iterator & it) {
if(*this != it){
mapit = it.mapit;
}
return *this;
}
iterator & operator++() {
++mapit;
return *this;
}
iterator operator++(int) {
iterator copy(*this);
operator++();
return copy;
}
bool operator==(const iterator & rhs) {
return mapit == rhs.mapit;
}
bool operator!=(const iterator & rhs) {
return !(*this == rhs);
}
ValueType operator*() {
return *mapit;
}
ValueType *operator->() {
return mapit;
}
};
iterator begin() const {
return iterator(map.begin());
}
iterator end() const {
return iterator(map.end());
}
};
extern void error(std::string msg);
template
Set::Set() {
/* Empty */
}
template
Set::~Set() {
/* Empty */
}
template
int Set::size() const {
return map.size();
}
template
bool Set::isEmpty() const {
return map.isEmpty();
}
template
void Set::add(const ValueType & value) {
map.put(value, true);
}
template
void Set::insert(const ValueType & value) {
map.put(value, true);
}
template
void Set::remove(const ValueType & value) {
map.remove(value);
}
template
bool Set::contains(const ValueType & value) const {
return map.containsKey(value);
}
template
void Set::clear() {
map.clear();
}
template
bool Set::isSubsetOf(const Set & set2) const {
iterator it = begin();
iterator end = this->end();
while (it != end) {
if (!set2.map.containsKey(*it)) return false;
++it;
}
return true;
}
/*
* Implementation notes: set operators
* -----------------------------------
* The implementations for the set operators use iteration to walk
* over the elements in one or both sets.
*/
template
bool Set::operator==(const Set & set2) const {
if (size() != set2.map.size()) return false;
iterator it1 = begin();
iterator it2 = set2.map.begin();
iterator end = this->end();
while (it1 != end) {
if (map.compareKeys(*it1, *it2) != 0) return false;
++it1;
++it2;
}
return true;
}
template
bool Set::operator!=(const Set & set2) const {
return !(*this == set2);
}
template
Set Set::operator+(const Set & set2) const {
Set set = *this;
foreach (ValueType value in set2) {
set.add(value);
}
return set;
}
template
Set Set::operator+(const ValueType & element) const {
Set set = *this;
set.add(element);
return set;
}
template
Set Set::operator*(const Set & set2) const {
Set set = *this;
set.clear();
foreach (ValueType value in *this) {
if (set2.contains(value)) set.add(value);
}
return set;
}
template
Set Set::operator-(const Set & set2) const {
Set set = *this;
foreach (ValueType value in set2) {
set.remove(value);
}
return set;
}
template
Set Set::operator-(const ValueType & element) const {
Set set = *this;
set.remove(element);
return set;
}
template
Set & Set::operator+=(const Set & set2) {
foreach (ValueType value in set2) {
this->add(value);
}
return *this;
}
template
Set & Set::operator+=(const ValueType & value) {
this->add(value);
this->removeFlag = false;
return *this;
}
template
Set & Set::operator*=(const Set & set2) {
Vector toRemove;
foreach (ValueType value in *this) {
if (!set2.map.containsKey(value)) toRemove.add(value);
}
foreach (ValueType value in toRemove) {
this->remove(value);
}
return *this;
}
template
Set & Set::operator-=(const Set & set2) {
Vector toRemove;
foreach (ValueType value in *this) {
if (set2.map.containsKey(value)) toRemove.add(value);
}
foreach (ValueType value in toRemove) {
this->remove(value);
}
return *this;
}
template
Set & Set::operator-=(const ValueType & value) {
this->remove(value);
this->removeFlag = true;
return *this;
}
template
ValueType Set::first() const {
if (isEmpty()) error("first: set is empty");
return *begin();
}
template
std::string Set::toString() {
ostringstream os;
os << *this;
return os.str();
}
template
void Set::mapAll(void (*fn)(ValueType)) const {
map.mapAll(fn);
}
template
void Set::mapAll(void (*fn)(const ValueType &)) const {
map.mapAll(fn);
}
template
template
void Set::mapAll(FunctorType fn) const {
map.mapAll(fn);
}
template
std::ostream & operator<<(std::ostream & os, const Set & set) {
os << "{";
bool started = false;
foreach (ValueType value in set) {
if (started) os << ", ";
writeGenericValue(os, value, true);
started = true;
}
os << "}";
return os;
}
template
std::istream & operator>>(std::istream & is, Set & set) {
char ch;
is >> ch;
if (ch != '{') error("operator >>: Missing {");
set.clear();
is >> ch;
if (ch != '}') {
is.unget();
while (true) {
ValueType value;
readGenericValue(is, value);
set += value;
is >> ch;
if (ch == '}') break;
if (ch != ',') {
error(std::string("operator >>: Unexpected character ") + ch);
}
}
}
return is;
}
// hashing functions for sets; defined in hashmap.cpp
int hashCode(const Set& s);
int hashCode(const Set& s);
int hashCode(const Set& s);
int hashCode(const Set& s);
int hashCode(const Set& s);
#endif