00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #ifndef HASHARRAY_H_JUL_19_2005
00067 #define HASHARRAY_H_JUL_19_2005
00068
00069 #include <stdlib.h>
00070 #include <assert.h>
00071 #include <iostream>
00072 #include <string>
00073 #include "random.h"
00074 using namespace std;
00075 #include <ext/hash_map>
00076 using namespace __gnu_cxx;
00077
00078
00079
00080 template <typename Type, class HashFn, class EqualFn>
00081 class HashArray
00082 {
00083 public:
00084 HashArray(const int& initSize=0) : items_(NULL), maxItems_(0), numItems_(0),
00085 map_(new hash_map<Type,int,HashFn,EqualFn>)
00086 { allocateMemory(initSize); }
00087
00088
00089 HashArray(const HashArray<Type, HashFn, EqualFn>& x)
00090 {
00091 if (x.numItems_ == 0)
00092 {
00093 items_ = NULL;
00094 maxItems_ = 0;
00095 numItems_ = 0;
00096 allocateMemory(0);
00097 map_ = new hash_map<Type, int, HashFn, EqualFn>;
00098 return;
00099 }
00100
00101 items_ = new Type[x.numItems_];
00102
00103
00104 for (int i = 0; i < x.numItems_; i++) items_[i] = x.items_[i];
00105 numItems_ = x.numItems_;
00106 maxItems_ = numItems_;
00107 map_ = new hash_map<Type, int, HashFn, EqualFn>;
00108 for (int i = 0; i < numItems_; i++)
00109 (*map_)[items_[i]] = i;
00110 assert(map_->size() == (unsigned int) numItems_);
00111 }
00112
00113
00114
00115 ~HashArray() { if (items_) delete [] items_; delete map_; }
00116
00117
00118
00119 int append(Type item)
00120 {
00121 if (map_->find(item) != map_->end()) return -1;
00122
00123 if (numItems_ == maxItems_)
00124 allocateMemory(maxItems_*2+1);
00125 items_[numItems_++] = item;
00126 (*map_)[item] = numItems_-1;
00127
00128 assert(map_->size() == (unsigned int) numItems_);
00129 return numItems_-1;
00130 }
00131
00132
00133 int append(Type item, const int& max)
00134 {
00135 if (map_->find(item) != map_->end()) return -1;
00136
00137 if (numItems_ == maxItems_)
00138 {
00139 int newNumItems = maxItems_*2+1;
00140 if (newNumItems > max) newNumItems = max;
00141 allocateMemory(newNumItems);
00142 }
00143 items_[numItems_++] = item;
00144 (*map_)[item] = numItems_-1;
00145 assert(map_->size() == (unsigned int) numItems_);
00146 return numItems_-1;
00147 }
00148
00149
00150
00151
00152 int append(const HashArray<Type, HashFn, EqualFn>& newItems)
00153 {
00154 int n = 0;
00155 for (int i = 0; i < newItems.size(); i++)
00156 if (append(newItems[i]) >= 0) n++;
00157 return n;
00158 }
00159
00160
00161 int append(const HashArray<Type, HashFn, EqualFn>* const & items)
00162 { return append(*items); }
00163
00164
00165
00166
00167
00168 int copyFrom(const HashArray<Type, HashFn, EqualFn>& items)
00169 {
00170 clear();
00171 return append(items);
00172 }
00173
00174
00175 HashArray<Type, HashFn, EqualFn>&
00176 operator=(const HashArray<Type, HashFn, EqualFn>& x)
00177 {
00178 copyFrom(x);
00179 return *this;
00180 }
00181
00182
00183 bool growToSize(const int& newSize)
00184 {
00185 if (newSize <= numItems_) return false;
00186
00187 if (newSize <= maxItems_)
00188 numItems_ = newSize;
00189 else
00190 {
00191 allocateMemory(newSize);
00192 numItems_ = newSize;
00193 }
00194 return true;
00195 }
00196
00197
00198 bool growToSize(const int& newSize, Type fill)
00199 {
00200 int origNumItems = numItems_;
00201 if(!growToSize(newSize)) return false;
00202 for (int i = origNumItems; i < numItems_; i++)
00203 items_[i] = fill;
00204 return true;
00205 }
00206
00207
00208
00209 void clear() { numItems_ = 0; map_->clear(); }
00210
00211
00212 void clearAndCompress() { numItems_ = 0; map_->clear(); compress(); }
00213
00214
00215
00216
00217 void deleteItemsAndClear()
00218 {
00219 for (int i = 0; i < numItems_; i++)
00220 if (items_[i]) delete items_[i];
00221 clear();
00222 assert(map_->size() == (unsigned int) numItems_);
00223 }
00224
00225
00226
00227 void deleteItemsAndClearCompress()
00228 {
00229 for (int i = 0; i < numItems_; i++)
00230 if (items_[i]) delete items_[i];
00231 clear();
00232 assert(map_->size() == (unsigned int) numItems_);
00233 compress();
00234 }
00235
00236
00237 int size() const { return numItems_; }
00238
00239 bool empty() const { return size()==0; }
00240
00241
00242
00243
00244 const Type& operator[](const int& index) const { return item(index); }
00245
00246
00247 Type& lastItem() const { return items_[numItems_-1]; }
00248
00249
00250
00251 const Type* getItems() const { return items_; }
00252
00259 int find(Type const & item) const
00260 {
00261 typename hash_map<Type, int, HashFn, EqualFn>::iterator it=map_->find(item);
00262 if (it == map_->end()) return -1;
00263 assert((*it).second >= 0);
00264 return (*it).second;
00265 }
00266
00267
00268 bool contains(Type const & item) const { return find(item) >= 0;}
00269
00270
00271 Type removeItem(const int& index)
00272 {
00273
00274 Type removedItem = items_[index];
00275 map_->erase(map_->find(items_[index]));
00276 for (int i = index+1; i < numItems_; i++) items_[i-1] = items_[i];
00277
00278
00279
00280
00281
00282
00283 numItems_--;
00284
00285
00286 typename hash_map<Type, int, HashFn, EqualFn>::iterator it;
00287 for (int i = index; i < numItems_; i++)
00288 {
00289 it = map_->find(items_[i]);
00290 assert(it != map_->end());
00291 assert((*it).second-1==i);
00292 (*it).second = i;
00293 }
00294
00295 assert(map_->size() == (unsigned int)numItems_);
00296 return removedItem;
00297 }
00298
00299
00300
00301
00302 Type removeInputItem(Type & item)
00303 {
00304 int idx = find(item);
00305 if (idx < 0) return NULL;
00306 return removeItem(idx);
00307 }
00308
00309 Type removeLastItem() { return removeItem(numItems_-1); }
00310
00311
00312 Type removeItemFastDisorder(const int& index)
00313 {
00314 Type removedItem = items_[index];
00315 map_->erase(map_->find(items_[index]));
00316
00317 if (numItems_ > 1 && index != numItems_-1)
00318 {
00319 map_->erase(map_->find(items_[numItems_-1]));
00320 (*map_)[items_[numItems_-1]] = index;
00321 item(index) = item(numItems_-1);
00322 }
00323
00324 numItems_--;
00325 assert(map_->size() == (unsigned int)numItems_);
00326 return removedItem;
00327 }
00328
00329
00330
00331 Type removeInputItemFastDisorder(Type & item)
00332 {
00333 int idx = find(item);
00334 if (idx < 0) return NULL;
00335 return removeItemFastDisorder(idx);
00336 }
00337
00338
00339
00340 void compress() { if (maxItems_ > numItems_) allocateMemory(numItems_); }
00341
00342
00343
00344 void shuffle()
00345 {
00346 for (int i = 0; i < numItems_; i++)
00347 {
00348
00349 int swapwith = Random::randomOneOf(numItems_);
00350 Type tmp;
00351 tmp = items_[i];
00352 items_[i] = items_[swapwith];
00353 items_[swapwith] = tmp;
00354 }
00355 }
00356
00357
00358
00359 int getMaxIndex()
00360 {
00361 assert(numItems_ > 0);
00362 int max = 0;
00363 for (int i = 1; i < numItems_; i++)
00364 {
00365 if (items_[i] > items_[max])
00366 max = i;
00367 }
00368 return max;
00369 }
00370
00371
00372
00373 Type getMaxValue()
00374 {
00375 assert(numItems_ > 0);
00376 Type max = items_[0];
00377 for (int i = 1; i < numItems_; i++)
00378 {
00379 if (items_[i] > max)
00380 max = items_[i];
00381 }
00382 return max;
00383 }
00384
00385
00386 private:
00387 Type& item(const int& index) const
00388 {
00389 assert(index < numItems_);
00390 return items_[index];
00391 }
00392
00393
00394 void allocateMemory(const int& newSize)
00395 {
00396 if (newSize > 0)
00397 {
00398 if (newSize >= numItems_)
00399 {
00400 Type* tempItems = new Type[newSize];
00401 if (numItems_ > 0)
00402 {
00403
00404
00405 for (int i = 0; i < numItems_; i++) tempItems[i] = items_[i];
00406 }
00407 delete [] items_;
00408 items_ = tempItems;
00409 maxItems_ = newSize;
00410 }
00411 else
00412 {
00413 Type* tempItems = new Type[newSize];
00414 if (numItems_ > 0)
00415 {
00416
00417
00418 for (int i = 0; i < newSize; i++) tempItems[i] = items_[i];
00419 }
00420 delete [] items_;
00421 items_ = tempItems;
00422 maxItems_ = newSize;
00423 numItems_ = newSize;
00424 }
00425 }
00426 else
00427 {
00428 delete [] items_;
00429 items_ = NULL;
00430 maxItems_ = 0;
00431 numItems_ = 0;
00432 }
00433 }
00434
00435
00436 private:
00437 Type* items_;
00438 int maxItems_;
00439 int numItems_;
00440
00441 hash_map<Type, int, HashFn, EqualFn>* map_;
00442 };
00443
00444
00445
00446
00447
00448 template <typename T, class HashFn, class EqualFn>
00449 void writeHashArray(const HashArray<T*,HashFn,EqualFn>& array, ostream& out,
00450 char* between, const char& delimiter)
00451 {
00452 out << array.size() << delimiter;
00453 for (int i = 0; i < array.size(); i++)
00454 {
00455 array.item(i)->save(out);
00456 if (between) out << between;
00457 }
00458 }
00459
00460
00461 template <typename T, class HashFn, class EqualFn>
00462 void writeArray(HashArray<T*,HashFn,EqualFn>& array, ostream& out,
00463 char* between=NULL)
00464 { writeArray(array, out, between, '\n'); }
00465
00466
00467 template <typename T, class HashFn, class EqualFn>
00468 void readArray(HashArray<T*,HashFn,EqualFn>& array, istream& in)
00469 {
00470 int numItems;
00471 in >> numItems;
00472 for (int i = 0; i < numItems && in.good(); i++)
00473 {
00474 T* x = new T;
00475 x->load(in);
00476 array.append(x);
00477 }
00478 }
00479
00480
00481 template <typename T, class HashFn, class EqualFn>
00482 void writeArray(HashArray<T,HashFn,EqualFn>& array, ostream& out,
00483 char* between, const char& delimiter)
00484 {
00485 out << array.Size() << delimiter;
00486 for (int i = 0; i < array.Size(); i++)
00487 {
00488 array.item(i).save(out);
00489 if (between) out << between;
00490 }
00491 }
00492
00493
00494 template <typename T, class HashFn, class EqualFn>
00495 void writeArray(HashArray<T,HashFn,EqualFn>& array, ostream& out,
00496 char* between=NULL)
00497 { writeArray(array, out, between, '\n'); }
00498
00499
00500 template <typename T, class HashFn, class EqualFn>
00501 void readArray(HashArray<T,HashFn,EqualFn>& array, istream& in)
00502 {
00503 int numItems;
00504 in >> numItems;
00505 for (int i = 0; i < numItems && in.good(); i++)
00506 {
00507 T x;
00508 x.load(in);
00509 array.append(x);
00510 }
00511 }
00512
00513
00514 template <typename T, class HashFn, class EqualFn>
00515 void writeBasicArray(HashArray<T,HashFn,EqualFn>& array, ostream& out,
00516 char* between, const char& delimiter)
00517 {
00518 out << array.Size() << delimiter;
00519 for (int i = 0; i < array.Size(); i++)
00520 {
00521 out << array.item(i) << " ";
00522 if (between) out << between;
00523 }
00524 }
00525
00526
00527 template <typename T, class HashFn, class EqualFn>
00528 void writeBasicArray(HashArray<T,HashFn,EqualFn>& array, ostream& out,
00529 char* between=NULL)
00530 { writeBasicArray(array, out, between, '\n'); }
00531
00532
00533 template <typename T, class HashFn, class EqualFn>
00534 void readBasicArray(HashArray<T,HashFn,EqualFn>& array, istream& in)
00535 {
00536 int numItems=0;
00537 in >> numItems;
00538 for (int i = 0; i < numItems && in.good(); i++)
00539 {
00540 T x;
00541 in >> x;
00542 array.append(x);
00543 }
00544 if (!in.good())
00545 cout << "ERROR: readBasicArray(). Input not good." << endl;
00546 }
00547
00548
00549 #endif