動態陣列(C++)
阿新 • • 發佈:2022-05-26
#include<iostream> #include <sstream> #include<iterator> #include<algorithm> using namespace std; // 重寫copy程式碼 template<class iterator> void copy(iterator start, iterator end, iterator to) { // 從start複製到[to, to+end-start) while (start != end) *(to++) = *(start++); } template<class T> class linearList { public: virtual ~linearList() = default;; virtual bool empty() const = 0; /* 返回true,當且僅當線性表為空 */ virtual int size() const = 0; /* 返回線性表的元素個數 */ virtual T &get(int theIndex) const = 0; /* 返回索引為theIndex的元素 */ virtual int indexOf(const T &theElement) const = 0; /* 返回元素theElement第一次出現時的索引 */ virtual void erase(int theIndex) = 0; /* 刪除索引為theIndex的元素 */ virtual void insert(int theIndex, const T &theElement) = 0;/* 把theElement插入線性表中索引為theIndex的位置上 */ virtual void output(ostream &out) const = 0;/*把線性表插入輸出流*/ }; class illegalParameterValue { public: illegalParameterValue() : message("Illegal parameter value") {} explicit illegalParameterValue(char *theMessage) { message = theMessage; } explicit illegalParameterValue(const string &theMessage) { message = theMessage; cout << message << endl; } void outputMessage() { cout << message << endl; } private: string message; }; /* 改變一個一位陣列的長度*/ template<class T> void changeLength1D(T *&a, int oldLength, int newLength) { if (newLength < 0) /* 如果新表長小於0 */ throw illegalParameterValue("new length muse be >= 0"); /* 丟擲異常*/ T *temp = new T[newLength]; /* 申請新的陣列空間*/ int number = min(oldLength, newLength); /*過的原來陣列長度和現在陣列長度中較小者*/ copy(a, a + number, temp); /* 將原陣列中的資料放到新的陣列中*/ delete[] a; /* 刪除原來陣列的空間*/ a = temp; /*將新陣列空間的地址給原來的陣列名*/ } /* 類arrayList定義 * 定義抽象類linearList的派生類arrayList * 來實現抽象資料型別linearList */ template<class T> class arrayList : public linearList<T> { public: /* 建構函式,複製建構函式和構析函式 */ arrayList(int initialCapacity = 10); arrayList(const arrayList<T> &); ~arrayList() { delete[]element; } /* ADT方法 */ bool empty() const { return listSize == 0; } int size() const { return listSize; } T &get(int theIndex) const; int indexOf(const T &theElement) const; void erase(int theIndex); void insert(int theIndex, const T &theElement); void output(ostream &out) const; int capacity() const { return arrayLength; } protected: void checkIndex(int theIndex) const; T *element; /* 儲存線性表元素的一維陣列 */ int arrayLength; /* 一維陣列的容量 */ int listSize; /* 線性表的元素個數 */ }; template<class T> void arrayList<T>::checkIndex(int theIndex) const { if (theIndex < 0 || theIndex >= listSize) { ostringstream s; s << "index = " << theIndex << " size = " << listSize; throw illegalParameterValue(s.str()); } } template<class T> T &arrayList<T>::get(int theIndex) const { // 返回索引為theIndex的元素 // 若此元素不存在,則丟擲異常 checkIndex(theIndex); return element[theIndex]; } template<class T> int arrayList<T>::indexOf(const T &theElement) const { // 返回元素theElement第一次出現時的索引 // 若該元素不存在,則返回-1 // 查詢元素theElement int theIndex = (int) (find(element, element + listSize, theElement) - element); // 確定theElement是否找到 if (theIndex == listSize) // 沒有找到 return -1; else return theIndex; } template<class T> void arrayList<T>::erase(int theIndex) { // 刪除其索引為theIndex的元素 // 如果該元素不存在,則丟擲illegal checkIndex(theIndex); // 有效索引,移動其索引大於theIndex的元素 copy(element + theIndex + 1, element + listSize, element + theIndex); element[--listSize].~T(); // 呼叫構析函式 } // arrayList的建構函式 template<class T> arrayList<T>::arrayList(int initialCapacity) { // 建構函式 if (initialCapacity < 1) { ostringstream s; s << "Initial capacity = " << initialCapacity << " Must be > 0"; throw illegalParameterValue(s.str()); } arrayLength = initialCapacity; element = new T[arrayLength]; listSize = 0; } template<class T> arrayList<T>::arrayList(const arrayList<T> &theList) { // 複製建構函式 arrayLength = theList.arrayLength; listSize = theList.listSize; element = new T[arrayLength]; copy(theList.element, theList.element + listSize, element); } template<class T> void arrayList<T>::insert(int theIndex, const T &theElement) { // 在索引theIndex處插入元素theElement if (theIndex < 0 || theIndex > listSize) { // 無效索引 ostringstream s; s << "index = " << theIndex << " size = " << listSize; throw illegalParameterValue(s.str()); } // 有效索引,確認陣列是否已滿 if (listSize == arrayLength) { // 陣列空間已滿,陣列長度倍增 changeLength1D(element, arrayLength, arrayLength * 2); arrayLength *= 2; } // 把元素向右移動一個位置 copy_backward(element + theIndex, element + listSize, element + listSize + 1); element[theIndex] = theElement; ++listSize; } // 把一個線性表插入輸出流 template<class T> void arrayList<T>::output(ostream &out) const { copy(element, element + listSize, ostream_iterator<T>(cout, " ")); } // 過載<< template<class T> ostream &operator<<(ostream &out, const arrayList<T> &x) { x.output(out); return out; } int main() { auto *array1 = new arrayList<int>(100); arrayList<double> y(100); cout << *array1 << endl; cout << y << endl; return 0; }