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 bool growToSize(const int& newSize)
00176 {
00177 if (newSize <= numItems_) return false;
00178
00179 if (newSize <= maxItems_)
00180 numItems_ = newSize;
00181 else
00182 {
00183 allocateMemory(newSize);
00184 numItems_ = newSize;
00185 }
00186 return true;
00187 }
00188
00189
00190 bool growToSize(const int& newSize, Type fill)
00191 {
00192 int origNumItems = numItems_;
00193 if(!growToSize(newSize)) return false;
00194 for (int i = origNumItems; i < numItems_; i++)
00195 items_[i] = fill;
00196 return true;
00197 }
00198
00199
00200
00201 void clear() { numItems_ = 0; map_->clear(); }
00202
00203
00204 void clearAndCompress() { numItems_ = 0; map_->clear(); compress(); }
00205
00206
00207
00208
00209 void deleteItemsAndClear()
00210 {
00211 for (int i = 0; i < numItems_; i++)
00212 if (items_[i]) delete items_[i];
00213 clear();
00214 assert(map_->size() == (unsigned int) numItems_);
00215 }
00216
00217
00218
00219 void deleteItemsAndClearCompress()
00220 {
00221 for (int i = 0; i < numItems_; i++)
00222 if (items_[i]) delete items_[i];
00223 clear();
00224 assert(map_->size() == (unsigned int) numItems_);
00225 compress();
00226 }
00227
00228
00229 int size() const { return numItems_; }
00230
00231 bool empty() const { return size()==0; }
00232
00233
00234
00235
00236 const Type& operator[](const int& index) const { return item(index); }
00237
00238
00239 Type& lastItem() const { return items_[numItems_-1]; }
00240
00241
00242
00243 const Type* getItems() const { return items_; }
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00260 int find(Type const & item) const
00261 {
00262 typename hash_map<Type, int, HashFn, EqualFn>::iterator it=map_->find(item);
00263 if (it == map_->end()) return -1;
00264 assert((*it).second >= 0);
00265 return (*it).second;
00266 }
00267
00268
00269 bool contains(Type const & item) const { return find(item) >= 0;}
00270
00271
00272 Type removeItem(const int& index)
00273 {
00274
00275 Type removedItem = items_[index];
00276 map_->erase(map_->find(items_[index]));
00277 for (int i = index+1; i < numItems_; i++) items_[i-1] = items_[i];
00278
00279
00280
00281
00282
00283
00284 numItems_--;
00285
00286
00287 typename hash_map<Type, int, HashFn, EqualFn>::iterator it;
00288 for (int i = index; i < numItems_; i++)
00289 {
00290 it = map_->find(items_[i]);
00291 assert(it != map_->end());
00292 assert((*it).second-1==i);
00293 (*it).second = i;
00294 }
00295
00296 assert(map_->size() == (unsigned int)numItems_);
00297 return removedItem;
00298 }
00299
00300
00301 Type removeItem(Type& item)
00302 {
00303 int idx = find(item);
00304 return removeItem(idx);
00305 }
00306
00307
00308 Type removeLastItem() { return removeItem(numItems_-1); }
00309
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 Type removeItemFastDisorder(Type& item)
00331 {
00332 int idx = find(item);
00333 if (idx < 0) return NULL;
00334 return removeItemFastDisorder(idx);
00335 }
00336
00337
00338
00339 void compress() { if (maxItems_ > numItems_) allocateMemory(numItems_); }
00340
00341
00342
00343 void shuffle()
00344 {
00345 for (int i = 0; i < numItems_; i++)
00346 {
00347
00348 int swapwith = Random::randomOneOf(numItems_);
00349 Type tmp;
00350 tmp = items_[i];
00351 items_[i] = items_[swapwith];
00352 items_[swapwith] = tmp;
00353 }
00354 }
00355
00356
00357
00358 int getMaxIndex()
00359 {
00360 assert(numItems_ > 0);
00361 int max = 0;
00362 for (int i = 1; i < numItems_; i++)
00363 {
00364 if (items_[i] > items_[max])
00365 max = i;
00366 }
00367 return max;
00368 }
00369
00370
00371
00372 Type getMaxValue()
00373 {
00374 assert(numItems_ > 0);
00375 Type max = items_[0];
00376 for (int i = 1; i < numItems_; i++)
00377 {
00378 if (items_[i] > max)
00379 max = items_[i];
00380 }
00381 return max;
00382 }
00383
00384
00385 private:
00386 Type& item(const int& index) const
00387 {
00388 assert(index < numItems_);
00389 return items_[index];
00390 }
00391
00392
00393 void allocateMemory(const int& newSize)
00394 {
00395 if (newSize > 0)
00396 {
00397 if (newSize >= numItems_)
00398 {
00399 Type* tempItems = new Type[newSize];
00400 if (numItems_ > 0)
00401 {
00402
00403
00404 for (int i = 0; i < numItems_; i++) tempItems[i] = items_[i];
00405 }
00406 delete [] items_;
00407 items_ = tempItems;
00408 maxItems_ = newSize;
00409 }
00410 else
00411 {
00412 Type* tempItems = new Type[newSize];
00413 if (numItems_ > 0)
00414 {
00415
00416
00417 for (int i = 0; i < newSize; i++) tempItems[i] = items_[i];
00418 }
00419 delete [] items_;
00420 items_ = tempItems;
00421 maxItems_ = newSize;
00422 numItems_ = newSize;
00423 }
00424 }
00425 else
00426 {
00427 delete [] items_;
00428 items_ = NULL;
00429 maxItems_ = 0;
00430 numItems_ = 0;
00431 }
00432 }
00433
00434
00435 private:
00436 Type* items_;
00437 int maxItems_;
00438 int numItems_;
00439
00440 hash_map<Type, int, HashFn, EqualFn>* map_;
00441 };
00442
00443
00444
00445
00446
00447 template <typename T, class HashFn, class EqualFn>
00448 void writeHashArray(const HashArray<T*,HashFn,EqualFn>& array, ostream& out,
00449 char* between, const char& delimiter)
00450 {
00451 out << array.size() << delimiter;
00452 for (int i = 0; i < array.size(); i++)
00453 {
00454 array.item(i)->save(out);
00455 if (between) out << between;
00456 }
00457 }
00458
00459
00460 template <typename T, class HashFn, class EqualFn>
00461 void writeArray(HashArray<T*,HashFn,EqualFn>& array, ostream& out,
00462 char* between=NULL)
00463 { writeArray(array, out, between, '\n'); }
00464
00465
00466 template <typename T, class HashFn, class EqualFn>
00467 void readArray(HashArray<T*,HashFn,EqualFn>& array, istream& in)
00468 {
00469 int numItems;
00470 in >> numItems;
00471 for (int i = 0; i < numItems && in.good(); i++)
00472 {
00473 T* x = new T;
00474 x->load(in);
00475 array.append(x);
00476 }
00477 }
00478
00479
00480 template <typename T, class HashFn, class EqualFn>
00481 void writeArray(HashArray<T,HashFn,EqualFn>& array, ostream& out,
00482 char* between, const char& delimiter)
00483 {
00484 out << array.Size() << delimiter;
00485 for (int i = 0; i < array.Size(); i++)
00486 {
00487 array.item(i).save(out);
00488 if (between) out << between;
00489 }
00490 }
00491
00492
00493 template <typename T, class HashFn, class EqualFn>
00494 void writeArray(HashArray<T,HashFn,EqualFn>& array, ostream& out,
00495 char* between=NULL)
00496 { writeArray(array, out, between, '\n'); }
00497
00498
00499 template <typename T, class HashFn, class EqualFn>
00500 void readArray(HashArray<T,HashFn,EqualFn>& array, istream& in)
00501 {
00502 int numItems;
00503 in >> numItems;
00504 for (int i = 0; i < numItems && in.good(); i++)
00505 {
00506 T x;
00507 x.load(in);
00508 array.append(x);
00509 }
00510 }
00511
00512
00513 template <typename T, class HashFn, class EqualFn>
00514 void writeBasicArray(HashArray<T,HashFn,EqualFn>& array, ostream& out,
00515 char* between, const char& delimiter)
00516 {
00517 out << array.Size() << delimiter;
00518 for (int i = 0; i < array.Size(); i++)
00519 {
00520 out << array.item(i) << " ";
00521 if (between) out << between;
00522 }
00523 }
00524
00525
00526 template <typename T, class HashFn, class EqualFn>
00527 void writeBasicArray(HashArray<T,HashFn,EqualFn>& array, ostream& out,
00528 char* between=NULL)
00529 { writeBasicArray(array, out, between, '\n'); }
00530
00531
00532 template <typename T, class HashFn, class EqualFn>
00533 void readBasicArray(HashArray<T,HashFn,EqualFn>& array, istream& in)
00534 {
00535 int numItems=0;
00536 in >> numItems;
00537 for (int i = 0; i < numItems && in.good(); i++)
00538 {
00539 T x;
00540 in >> x;
00541 array.append(x);
00542 }
00543 if (!in.good())
00544 cout << "ERROR: readBasicArray(). Input not good." << endl;
00545 }
00546
00547
00548 #endif