// A module of KPLib v1.4.2. // Written by Keith Pomakis during the summer of 1994. // Released to the public domain on October 10, 1994. // This version released on March 30, 1999. #ifndef KP_ARRAY_DEFINED #define KP_ARRAY_DEFINED #include #include #include "KPbasic.h" // Assumes Element has a default constructor and operator=(). template class KPArray { public: KPArray(); KPArray(int size); KPArray(int size, const Element &init_element); KPArray(const KPArray &array); virtual ~KPArray(); KPArray &operator=(const KPArray &array); Element &operator[](int index); const Element &operator[](int index) const; int size() const; bool is_empty() const; void resize(int new_size); void resize(int new_size, const Element &init_element); void set_all_to(const Element &element); protected: static void error(const char *msg); int my_size; Element *my_elements; }; // Assumes Element has the above plus operator==(). template class KPComparableArray: public KPArray { public: KPComparableArray(); KPComparableArray(int size); KPComparableArray(int size, const Element &init_element); KPComparableArray(const KPComparableArray &array); KPComparableArray(const KPArray &array); virtual ~KPComparableArray(); KPComparableArray &operator=(const KPArray &array); bool operator==(const KPComparableArray &array) const; bool operator!=(const KPComparableArray &array) const; bool contains(const Element &element) const; int occurrences_of(const Element &element) const; int index_of(const Element &element) const; protected: static void error(const char *msg); }; // Assumes Element has the above plus operator<(). Note that this operator // must place a total ordering on the set of Elements. template class KPSortableArray: public KPComparableArray { public: KPSortableArray(); KPSortableArray(int size); KPSortableArray(int size, const Element &init_element); KPSortableArray(const KPSortableArray &array); KPSortableArray(const KPArray &array); virtual ~KPSortableArray(); KPSortableArray &operator=(const KPArray &array); void sort(); Element &min(); const Element &min() const; Element &max(); const Element &max() const; protected: static void error(const char *msg); int findpivot(int i, int j); int partition(int l, int r, const Element &pivot); void quicksort(int i, int j); }; /****************************************************************************/ template inline KPArray::KPArray(): my_size(0) { /* do nothing */ } /****************************************************************************/ template KPArray::KPArray(int size) { if (size < 0) error("KPArray() - size of KPArray must be non-negative"); my_size = size; my_elements = new Element[size]; check_mem(my_elements); } /****************************************************************************/ template KPArray::KPArray(int size, const Element &init_element) { if (size < 0) error("KPArray() - size of KPArray must be non-negative"); my_size = size; if (my_size > 0) { my_elements = new Element[size]; check_mem(my_elements); for (int i=0; i KPArray::KPArray(const KPArray &array) { my_size = array.my_size; if (my_size > 0) { my_elements = new Element[my_size]; check_mem(my_elements); for (int i=0; i inline KPArray::~KPArray() { if (my_size > 0) delete [] my_elements; } /****************************************************************************/ template KPArray & KPArray::operator=(const KPArray &array) { if (this == &array) return *this; bool resize = (my_size != array.my_size); if (my_size > 0 && resize) delete [] my_elements; my_size = array.my_size; if (my_size > 0) { if (resize) { my_elements = new Element[my_size]; check_mem(my_elements); } for (int i=0; i inline Element & KPArray::operator[](int index) { if (index < 0 || index >= my_size) error("operator[] - invalid index"); return my_elements[index]; } /****************************************************************************/ template inline const Element & KPArray::operator[](int index) const { if (index < 0 || index >= my_size) error("operator[] - invalid index"); return my_elements[index]; } /****************************************************************************/ template inline int KPArray::size() const { return my_size; } /****************************************************************************/ template inline bool KPArray::is_empty() const { return (my_size == 0); } /****************************************************************************/ template void KPArray::resize(int new_size) { if (my_size == new_size) return; if (new_size < 0) error("resize() - size of KPArray must be non-negative"); if (new_size > 0) { Element *new_space = new Element[new_size]; check_mem(new_space); const int savable_elements = ::min(my_size, new_size); for (int i=0; i 0) delete [] my_elements; my_elements = new_space; } else delete [] my_elements; my_size = new_size; } /****************************************************************************/ template void KPArray::resize(int new_size, const Element &init_element) { if (my_size == new_size) return; if (new_size < 0) error("resize() - size of KPArray must be non-negative"); if (new_size > 0) { Element *new_space = new Element[new_size]; check_mem(new_space); int i; const int savable_elements = ::min(my_size, new_size); for (i=0; i 0) delete [] my_elements; my_elements = new_space; for (i=my_size; i void KPArray::set_all_to(const Element &element) { for (int i=0; i void KPArray::error(const char *msg) { cerr << "KPArray: " << msg << '\n'; exit(EXIT_FAILURE); } /****************************************************************************/ template inline KPComparableArray::KPComparableArray(): KPArray() { /* do nothing new. */ } /****************************************************************************/ template inline KPComparableArray::KPComparableArray(int size): KPArray(size) { /* do nothing new. */ } /****************************************************************************/ template inline KPComparableArray::KPComparableArray(int size, const Element &init_element): KPArray(size, init_element) { /* do nothing new. */ } /****************************************************************************/ template inline KPComparableArray::KPComparableArray( const KPComparableArray &array): KPArray(array) { /* do nothing new. */ } /****************************************************************************/ template inline KPComparableArray::KPComparableArray(const KPArray &array): KPArray(array) { /* do nothing new. */ } /****************************************************************************/ template inline KPComparableArray::~KPComparableArray() { /* do nothing new. */ } /****************************************************************************/ template inline KPComparableArray & KPComparableArray::operator=(const KPArray &array) { KPArray::operator=(array); return *this; } /****************************************************************************/ template bool KPComparableArray::operator==(const KPComparableArray &array) const { if (this == &array) return true; if (my_size != array.my_size) return false; for (int i=0; i inline bool KPComparableArray::operator!=(const KPComparableArray &array) const { return !(*this == array); } /****************************************************************************/ template inline bool KPComparableArray::contains(const Element &element) const { return (index_of(element) != -1); } /****************************************************************************/ template int KPComparableArray::occurrences_of(const Element &element) const { int occurrences = 0; for (int i=0; i int KPComparableArray::index_of(const Element &element) const { for (int i=0; i void KPComparableArray::error(const char *msg) { cerr << "KPComparableArray: " << msg << '\n'; exit(EXIT_FAILURE); } /****************************************************************************/ template inline KPSortableArray::KPSortableArray(): KPComparableArray() { /* do nothing new. */ } /****************************************************************************/ template inline KPSortableArray::KPSortableArray(int size): KPComparableArray(size) { /* do nothing new. */ } /****************************************************************************/ template inline KPSortableArray::KPSortableArray(int size, const Element &init_element): KPComparableArray(size, init_element) { /* do nothing new. */ } /****************************************************************************/ template inline KPSortableArray::KPSortableArray(const KPSortableArray &array): KPComparableArray(array) { /* do nothing new. */ } /****************************************************************************/ template inline KPSortableArray::KPSortableArray(const KPArray &array): KPComparableArray(array) { /* do nothing new. */ } /****************************************************************************/ template inline KPSortableArray::~KPSortableArray() { /* do nothing new. */ } /****************************************************************************/ template inline KPSortableArray & KPSortableArray::operator=(const KPArray &array) { KPComparableArray::operator=(array); return *this; } /****************************************************************************/ template int KPSortableArray::findpivot(int i, int j) { const Element &first = my_elements[i]; for (int k=i+1; k<=j; k++) { if (first < my_elements[k]) return k; else if (my_elements[k] < first) return i; } return -1; } template int KPSortableArray::partition(int l, int r, const Element &pivot) { do { swap(my_elements[l], my_elements[r]); while (my_elements[l] < pivot) l++; while (!(my_elements[r] < pivot)) r--; } while (l <= r); return l; } template void KPSortableArray::quicksort(int i, int j) { Element pivot; int k, index; index = findpivot(i, j); if (index != -1) { pivot = my_elements[index]; k = partition(i, j, pivot); quicksort(i, k-1); quicksort(k, j); } } template inline void KPSortableArray::sort() { quicksort(0, my_size-1); } /****************************************************************************/ template Element & KPSortableArray::min() { if (my_size < 1) error("min() - empty array"); int min_index = 0; for (int i=1; i const Element & KPSortableArray::min() const { if (my_size < 1) error("min() - empty array"); int min_index = 0; for (int i=1; i Element & KPSortableArray::max() { if (my_size < 1) error("max() - empty array"); int max_index = 0; for (int i=1; i const Element & KPSortableArray::max() const { if (my_size < 1) error("max() - empty array"); int max_index = 0; for (int i=1; i void KPSortableArray::error(const char *msg) { cerr << "KPSortableArray: " << msg << '\n'; exit(EXIT_FAILURE); } /****************************************************************************/ #endif /* KP_ARRAY_DEFINED */