1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
|
// Complete the implementation of the class ArrayDictionary as given in Listing 18-3.
/** An array-based implementation of the ADT dictionary
that organizes its data items in sorted search-key order.
Search keys in the dictionary are unique.
@file ArrayDictionary.h */
#pragma once
#ifndef _ARRAY_DICTIONARY
#define _ARRAY_DICTIONARY
#include "DictionaryInterface.h"
#include "Entry.h"
#include "NotFoundException.h"
#include "PrecondViolatedExcept.h"
template < class KeyType, class ValueType>
class ArrayDictionary : public DictionaryInterface < KeyType, ValueType>
{
private:
static const int DEFAULT_CAPACITY = 21; // Small capacity to test for
// a full dictionary
Entry<KeyType, ValueType>* entries; // Array of dictionary entries
int maxItems; // Maximum capacity of the dictionary
void destroyDictionary();
int findEntryIndex(int firstIndex, int lastIndex, const KeyType & searchKey) const;
int maxEntries;
public:
ArrayDictionary();
ArrayDictionary(int maxNumberOfEntries);
ArrayDictionary(const ArrayDictionary<KeyType, ValueType>&dictionary);
virtual ~ArrayDictionary();
bool isEmpty() const;
int getNumberOfEntries() const;
bool add(const KeyType& searchKey, const ValueType& newValue) throw (PrecondViolatedExcep);
bool remove(const KeyType& searchKey);
void clear();
ValueType getValue(const KeyType& searchKey) const throw (NotFoundException);
bool contains(const KeyType& searchKey) const;
/** Traverses the items in this dictionary in sorted search-key order
and calls a given client function once for each item. */
void traverse(void visit(ValueType&)) const;
}; // end ArrayDictionary
#include "ArrayDictionary.cpp"
#endif
// ArrayDictionary.cpp
#include <iostream>
#include "ArrayDictionary.h"
#include "PrecondViolatedExcept.cpp"
template < class KeyType, class ValueType>
inline void destroyDictionary()
{
delete[] items;
items = new Entry[maxItems];
itemsCount = 0;
}
template < class KeyType, class ValueType>
inline int findEntryIndex(int firstIndex, int lastIndex, const KeyType& searchKey)
{
int IndexMiddle = firstIndex + (lastIndex - firstIndex) / 2;
if (firstIndex > lastIndex)
return -1;
else if (searchKey == items[IndexMiddle].getKey())
return IndexMiddle;
else if (searchKey < items[IndexMiddle].getKey())
return findEntryIndex(firstIndex, IndexMiddle - 1, searchKey);
else
return findEntryIndex(IndexMiddle + 1, lastIndex, searchKey);
}
template < class KeyType, class ValueType>
inline ArrayDictionary::ArrayDictionary() : itemCount(0), maxItems(DEFAULT_CAPACITY)
{
items = new Entry[DEFAULT_CAPACITY];
}
template < class KeyType, class ValueType>
inline ArrayDictionary::ArrayDictionary(int maxNumberOfEntries) :
itemCount(0), maxItems(maxNumberOfEntries)
{
items = new Entry[maxNumberOfEntries];
}
template < class KeyType, class ValueType>
inline ArrayDictionary::ArrayDictionary(const ArrayDictionary& dictionary) :
itemCount(dict.itemCount), maxItems(dict.maxItems)
{
items = new Entry[dict.maxItems];
for (int index = 0; index < dict.itemCount; index++)
{
items[index] = dict.items[index];
}
}
template < class KeyType, class ValueType>
inline ArrayDictionary::~ArrayDictionary()
{
destroyDictionary()
}
template < class KeyType, class ValueType>
inline bool isEmpty()
{
return (itemCount == 0);
}
template < class KeyType, class ValueType>
inline int getNumberOfItems()
{
return itemCount;
}
template < class KeyType, class ValueType>
inline void clear()
{
destroyDictionary();
}
template < class KeyType, class ValueType>
inline bool ArrayDictionary<KeyType, ValueType>::add(const KeyType& searchKey, const ValueType& newValue) throw (PrecondViolatedExcep)
{
bool ableToInsert = (itemCount < maxItems);
if (ableToInsert)
{
// Make room for new entry by shifting all entries at
// positions >= newPosition toward the end of the array
// (no shift if newPosition == itemCount + 1). Performing
// a binary search doesn’t help here, because we need to
// shift the entries while looking for the insertion location.
int index = itemCount;
// Short-circuit evaluation is important
while ((index > 0) && (searchKey < items[index - 1].getKey()))
{
items[index] = items[index - 1];
index--;
} // end while
if (searchKey != items[index - 1].getKey())
{
items[index] = Entry<KeyType, ValueType>(searchKey, newValue);
itemCount++;
}
else
{
auto message = "Attempt to add entry whose search key exits in dictionary.";
throw (PrecondViolatedExcep(message);
}
return ableToInsert;
} // end add
}
template < class KeyType, class ValueType>
inline bool remove(const const KeyType& itemKey)
{
int currentIndex = findEntryIndex(0, itemCount - 1, itemKey);
bool deletable = !isEmpty() && (currentIndex >= 0);
if (deletable)
{
while (currentIndex < itemCount - 1)
{
items[currentIndex] = items[currentIndex + 1];
currentIndex++;
}
itemCount--;
}
return deletable;
}
template < class KeyType, class ValueType>
inline ValueType getValue(const KeyType& searchKey) throw(NotFoundException)
{
int currentIndex = findEntryIndex(0, itemCount - 1, searchKey);
if (currentIndex < 0)
throw NotFoundException("nnItemis not in the Dictionary!nn");
return items[currentIndex].getItem();
}
template < class KeyType, class ValueType>
inline bool contains(const KeyType& searchKey)
{
return (findEntryIndex(0, itemCount - 1, itemKey) >= 0)
}
template < class KeyType, class ValueType>
inline void traverse(void visit(ValueType&))
{
for (int itr = 0; itr < itemCount; itr++)
{
ValueType currentItem = items[itr].getItem();
visit(currentItem);
}
}
|