| |
| |
/ 17 \
/ 23 \
| 4 |
| 11 17|
\_______/
17
|
|
v
| | | |
| | | |
/ \ =====> / \
/ \ / \
| 4 | | 4 |
| | | 17 |
\_______/ \_______/
| | 4 | |
| ^ | | |
/ | \ =====> / \
/ | \ / \
| 4--| | | |
| 17 | | 17 |
\_______/ \_______/
| |
| |
/ * \
/ * \ =====> 5
| * |
| * * |
\_______/
| |
| |
/ \
/ \ =====> Yes
| |
| |
\_______/
| |
| |
/ * \
/ * \ =====> No
| * |
| * * |
\_______/
|***|
|***|
/*****\
/*******\ =====> Yes
|*********|
|*********|
\-------/
| |
| |
/ * \
/ * \ =====> No
| * |
| * * |
\_______/
The specifications for the bag operations can be found in the file bag.h.
The details of how some of the bag operations are specified can be found in the these postscript slides of Main & Savitch.
Some reminders about C++ member functions:
bool Bag::isEmpty() constindicates that the isEmpty member function of the Bag class does not modify the contents of the bag. It is like a static postcondition - a guarantee that after the function is called the state of the Bag will not have changed (static because the compiler can check it).
bool Bag::operator==(const Bag& operand) const
(1) (2) (3)
(1), the keyword operator indicates operator
overloading - the
== operator will have a user-supplied meaning rather than
the standard compiler meaning (if there is such a one).
(2), the keyword const indicates that the operand, supplied to the
function as an argument, will not be modified by the function - it is also
like a static postcondition. (3) The & in Bag& indicates
that the argument will be passed by reference (the address of
operand will be passed) rather than by value (a copy of
operand will be passed).
friend ostream& operator <<(ostream&, const Bag&)
(1) (2) (2)
(1), the keyword friend indicates that the function is not a
member of the class (in this case the Bag class), but the
function still has access to the class' private members. It is not
crucial that a user (as opposed to implementer) know a function is a
friend - since the user need not know which members are private. (2)
ostream is a class defined in the standard C++ library
iostream.h for referring to output devices.
static const size_t CAPACITY = 20;
(1) (2) (3)
(1) The keyword static indicates that all bags have the same
CAPACITY. (2) The keyword const indicates that
CAPACITY cannot change during program execution. (3) The
type size_t is defined in the C++ standard library
stdlib.h. It is an unsigned (non-negative) integer that is
designed for describing how many objects are stored in memory. Since
size_t is an unsigned type, beware of the following
situation:
size_t i;
i = 0;
i--; // i = i - 1
// i is not -1, but instead a large positive int
// this is usually BAD
The details of how some of the bag operations are implemented can also be found in the these postscript slides of Main & Savitch.
Other details are discussed below.
int Bag::grab()
{
int x;
size_t i;
i = rand() % count; // i will be in range 0<=i<count
x = data[i];
count--;
for(size_t j = i; j < count; j++)
data[j] = data[j+1];
return x;
}
An example of calling Bag::grab(). Consider the Bag represented as:
8 4 17 33 4 11 16
If the random int i is chosen to be 0 then the resulting array is:
4 17 33 4 11 16
Meaning that roughly count number of items of the data array had to be `slid over'. This makes grab slow for large Bags. (Slower than necessary - in fact, it is O(n) - see the notes on computational complexity.)
int Bag::grab()
{
int x;
size_t i;
i = rand() % count;
x = data[i];
count--;
data[i] = data[count];
return x;
}
The algorithm has a constant running time - it performs the same
number of operations regardless of how many items in are in the bag.
We would like to be able to formalize the notion that one algorithm is more efficient than another. This motivates our next topic: computational complexity.
Can we do better? Yes. We can make arrays B,C of the size of the two bags and sort b.data into B and c.data into C. Then b==c if and only if B and C have the same elements in the same order.
How fast is this version of bag equality? 2 sorting operations plus a walk through arrays B, C (which is O(n)), so the complexity it 2*sort-time + O(n). In general, sorting is worse than O(n) so, asymptotically, worst-case time is proportional to the sorting complexity.
For selection sort, bag equality would be O(n2 ) again. However, there are O(n*lg(n)) sorting algorithms (which we will learn about later in the semester). In the case of the faster sorting, bag equality can be done in O(n*lg(n)).
Drawbacks to the sorting method of bag equality include the memory overhead for the additional arrays and that for small bags this may actually be slower.