//AssocList.h // An AssocList f holds a set of(key, value) associations, // (just like a HashTable, except operations are slower) // // basic operations are: // // f[key] = value -- assign a value associated with key // value = f[key] -- retrieve the value associated with key. // If there was no association, allocate a new association // with the value optionally set to some default. // // f.exists(key) -- does key have a value associated with it? // f.remove(key) -- remove the association for key (if one exists) // // f.clear() -- remove all associations // // f.keys() -- return array of existing keys // f.values() -- return array of existing values // // also: copy constructor, operator=, operator<< // // use like this: // // #include "AssocList.h" // #include "AssocList.cc" // // ... // // AssocList<char *, int> h(-1); // with default initialization value // AssocList<char *, int> g; // without default initialization value // // h["hi"] = 3; // // Array<char *> keys = h.keys(); // // for (int i = 0; i < keys.size(); ++i) // cout << h[keys[i]] << endl; // // Array<int> keys = h.values(); // // h.remove("hi"); // // h.clear(); // // g = h; // deep copy by operator= // // if (h.exists("hi")) ... // test if "hi" is a key without creating an entry for it // // Implementated as an array of (key, value) pairs, so... // MOST OPERATIONS TAKE O(N) TIME, WHERE N IS THE NUMBER OF ASSOCIATIONS. // (only useful for small lists) #ifndef _ASSOCLIST_H #define _ASSOCLIST_H #include "Array.h" #include "Comparisons.h" #include <iostream.h> template <class KEY, class VALUE> class AssocList { public: // construct an AssocList default init value for new VALUES: AssocList(VALUE const & def); // construct an AssocList without any default init value AssocList(); // deep copy constructor AssocList(AssocList const & a); // assignment op (deep copy) AssocList& operator=(const AssocList& a); // destructor ~AssocList(); // reset to empty void clear(); // does key have an entry? int exists(KEY const & k) const; // remove entry of key void remove(KEY const & k); // return ref to value associated with key VALUE & operator[](KEY const & k); // return value associated with key, key must exist VALUE operator[](KEY const & k) const; // return array of all keys with entries Array<KEY> keys() const; // return array of all values associated with keys Array<VALUE> values() const; // output friend ostream & operator<< <>(ostream &, const AssocList<KEY,VALUE> &); private: // implementation is as array of (KEY,VALUE) pairs, // with non-replaced removed pairs marked "removed" struct Pair { KEY k; VALUE v; int removed; }; Array<Pair> pairs; int use_default; // 1 = use, 0 = don't use VALUE default_init; // only used if use_default = 1 int find(KEY const & k) const; // return index of pair with key k }; #endif