#include "stdstuff.h" #include "IntBag.h" static const int DEFAULT_CAPACITY = 10; void IntBag::copyFrom (const IntBag &otherBag){ int i; for (i = 0; i < otherBag.count; i++) { data[i] = otherBag.data[i]; } count = otherBag.count; walkInProgress = false; } IntBag::IntBag () { data = new int[DEFAULT_CAPACITY]; capacity = DEFAULT_CAPACITY; count = 0; walkInProgress = false; } IntBag::IntBag (int capacity) { data = new int[capacity]; this -> capacity = capacity; count = 0; walkInProgress = false; } /* original version ... IntBag::IntBag (const IntBag &otherBag) { int i; data = new int[otherBag.capacity]; capacity = otherBag.capacity; count = otherBag.count; for (i = 0; i < count; i++) { data[i] = otherBag.data[i]; } // Whether or not a walk is in progress for the other bag, // the bag being created should start off with a clean slate. walkInProgress = false; } ... */ // improved version (uses private method "copyFrom") IntBag::IntBag (const IntBag &otherBag) { data = new int[otherBag.capacity]; capacity = otherBag.capacity; copyFrom (otherBag); } IntBag::~IntBag () { delete [] data; } // adds a value to the bag. returns true on success (space available) // and false on failure (bag full) bool IntBag::add (int value) { if (count == capacity) return false; // "capacity" was MAXVALUES data[count++] = value; walkInProgress = false; // scrub any ongoing walk return true; } // removes one occurance of the specfied value from the bag. returns // true on success (value existed) and false on failure (value did not exist) bool IntBag::remove (int value) { int i; for (i = 0; i < count; i++) { if (data[i] == value) { // we've found the data value. // overwrite it with the last data value and adjust the count // to reflect the fact that there are now one fewer values in // the bag. note that this works even if the value being removed // is the last value in the bag. data[i] = data[--count]; walkInProgress = false; // scrub any ongoing walk return true; } } return false; } // returns the number of times that the specified value occurs in the bag int IntBag::countOccurrences (int value) const { int i, occurrences = 0; for (i = 0; i < count; i++) { if (data[i] == value) { occurrences++; } } return occurrences; } bool IntBag::startWalk (int &value) { if (count == 0) return false; walkInProgress = true; walkPosition = 0; value = data[walkPosition]; return true; } bool IntBag::continueWalk (int &value) { if (!walkInProgress) { throw range_error ("IntBag::continueWalk invalid call"); } if (++walkPosition == count) { walkInProgress = false; // we've come to the end of the road return false; } value = data[walkPosition]; return true; } // randomly picks and returns one of the values in the bag. // throws a range_error exception if the bag is empty. int IntBag::pickRandom () const { int i; if (count == 0) { throw range_error ("IntBag::pickRandom bag is empty"); } i = (int) ((rand () / (RAND_MAX + 1.0)) * count); return data[i]; } /* original version ... IntBag& IntBag::operator= (const IntBag &otherBag) { int i; // check that the bag being copied into is big enough and // throw an exception if it isn't if (capacity < otherBag.count) { throw overflow_error ("IntBag::operator= - target bag too small"); } // copy all data values and update count for (i = 0; i < otherBag.count; i++) { data[i] = otherBag.data[i]; } count = otherBag.count; // Whether or not a walk is in progress for the other bag, // the bag being assigned to should have no walk in progress. walkInProgress = false; // In C++, the assignment operator normally produces a value (the new // value of the left hand operator). This permits multiple assignments // and generally allows the use of "=" anywhere in an expression. // In keeping with this convention, we return the object being operated upon // (or, more correctly, a reference to it, which is more or less equivalent). return *this; } ... */ // improved version (uses private method "copyFrom") IntBag& IntBag::operator= (const IntBag &otherBag) { // check that the bag being copied into is big enough and // throw an exception if it isn't if (capacity < otherBag.count) { throw overflow_error ("IntBag::operator= - target bag too small"); } copyFrom (otherBag); return *this; }