1 #include<iostream> 2 #include<sstream> 3 #include<string> 4 #include<algorithm> 5 #include<iterator> 6 7 using namespace std; 8 9 template<class T> 10 class arrayList 11 { 12 public: 13 // constructor, copy constructor and destructor 14 arrayList(int initialCapacity = 10); 15 arrayList(const arrayList<T>&); 16 ~arrayList() { delete[] element; } 17 18 // ADT methods 19 bool empty() const { return listSize == 0; } 20 int size() const { return listSize; } 21 T& get(int theIndex) const; 22 int indexOf(const T& theElement) const; 23 void erase(int theIndex); 24 void insert(int theIndex, const T& theElement); 25 void output(ostream& out) const; 26 27 // additional method 28 int capacity() const { return arrayLength; } 29 30 protected: 31 void checkIndex(int theIndex) const; 32 // throw illegalIndex if theIndex invalid 33 T* element; // 1D array to hold list elements 34 int arrayLength; // capacity of the 1D array 35 int listSize; // number of elements in list 36 }; 37 38 template<class T> 39 arrayList<T>::arrayList(int initialCapacity) 40 {// Constructor. 41 if (initialCapacity < 1) 42 { 43 ostringstream s; 44 s << "Initial capacity = " << initialCapacity << " Must be > 0"; 45 } 46 arrayLength = initialCapacity; 47 element = new T[arrayLength]; 48 listSize = 0; 49 } 50 51 template<class T> 52 arrayList<T>::arrayList(const arrayList<T>& theList) 53 {// Copy constructor. 54 arrayLength = theList.arrayLength; 55 listSize = theList.listSize; 56 element = new T[arrayLength]; 57 copy(theList.element, theList.element + listSize, element); 58 } 59 60 template<class T> 61 void arrayList<T>::checkIndex(int theIndex) const 62 {// Verify that theIndex is between 0 and listSize - 1. 63 if (theIndex < 0 || theIndex >= listSize) 64 { 65 ostringstream s; 66 s << "index = " << theIndex << " size = " << listSize; 67 } 68 } 69 70 template<class T> 71 T& arrayList<T>::get(int theIndex) const 72 {// Return element whose index is theIndex. 73 // Throw illegalIndex exception if no such element. 74 checkIndex(theIndex); 75 return element[theIndex]; 76 } 77 78 template<class T> 79 int arrayList<T>::indexOf(const T& theElement) const 80 {// Return index of first occurrence of theElement. 81 // Return -1 if theElement not in list. 82 83 // search for theElement 84 int theIndex = (int)(find(element, element + listSize, theElement) - element); 85 // check if theElement was found 86 if (theIndex == listSize) 87 // not found 88 return -1; 89 else return theIndex; 90 } 91 92 template<class T> 93 void arrayList<T>::erase(int theIndex) 94 {// Delete the element whose index is theIndex. 95 // Throw illegalIndex exception if no such element. 96 checkIndex(theIndex); 97 98 // valid index, shift elements with higher index 99 copy(element + theIndex + 1, element + listSize, 100 element + theIndex); 101 102 element[--listSize].~T(); // invoke destructor 103 } 104 105 template<class T> 106 void changeLength1D(T*& a, int oldLength, int newLength) 107 { 108 if (newLength < 0) 109 cout<<"new length must be >= 0"; 110 111 T* temp = new T[newLength]; // new array 112 int number = min(oldLength, newLength); // number to copy 113 copy(a, a + number, temp); 114 delete[] a; // deallocate old memory 115 a = temp; 116 } 117 118 template<class T> 119 void arrayList<T>::insert(int theIndex, const T& theElement) 120 {// Insert theElement so that its index is theIndex. 121 if (theIndex < 0 || theIndex > listSize) 122 {// invalid index 123 ostringstream s; 124 s << "index = " << theIndex << " size = " << listSize; 125 } 126 127 // valid index, make sure we have space 128 if (listSize == arrayLength) 129 {// no space, double capacity 130 changeLength1D(element, arrayLength, 2 * arrayLength); 131 arrayLength *= 2; 132 } 133 134 // shift elements right one position 135 copy_backward(element + theIndex, element + listSize, 136 element + listSize + 1); 137 138 element[theIndex] = theElement; 139 140 listSize++; 141 } 142 143 template<class T> 144 void arrayList<T>::output(ostream& out) const 145 {// Put the list into the stream out. 146 copy(element, element + listSize, ostream_iterator<T>(cout, " ")); 147 } 148 149 // overload << 150 template <class T> 151 ostream& operator<<(ostream& out, const arrayList<T>& x) 152 { 153 x.output(out); return out; 154 }
1 // test the class arrayList that uses STL algorithms 2 3 int main() 4 { 5 // test constructor 6 arrayList<double> *x = new arrayList<double>(20); 7 arrayList<int> y(2), z; 8 9 // test capacity 10 cout << "Capacity of x, y and z = " 11 << ((arrayList<double>*) x)->capacity() << ", " 12 << y.capacity() << ", " 13 << z.capacity() << endl; 14 15 16 // test size 17 cout << "Initial size of x, y, and z = " 18 << x->size() << ", " 19 << y.size() << ", " 20 << z.size() << endl; 21 22 // test empty 23 if (x->empty()) cout << "x is empty" << endl; 24 else cout << "x is not empty" << endl; 25 if (y.empty()) cout << "y is empty" << endl; 26 else cout << "y is not empty" << endl; 27 28 // test insert 29 y.insert(0, 2); 30 y.insert(1, 6); 31 y.insert(0, 1); 32 y.insert(2, 4); 33 y.insert(3, 5); 34 y.insert(2, 3); 35 cout << "Inserted 6 integers, list y should be 1 2 3 4 5 6" << endl; 36 cout << "Size of y = " << y.size() << endl; 37 cout << "Capacity of y = " << y.capacity() << endl; 38 if (y.empty()) cout << "y is empty" << endl; 39 else cout << "y is not empty" << endl; 40 y.output(cout); 41 cout << endl << "Testing overloaded <<" << endl; 42 cout << y << endl; 43 44 // test indexOf 45 int index = y.indexOf(4); 46 if (index < 0) cout << "4 not found" << endl; 47 else cout << "The index of 4 is " << index << endl; 48 49 index = y.indexOf(7); 50 if (index < 0) cout << "7 not found" << endl; 51 else cout << "The index of 7 is " << index << endl; 52 53 // test get 54 cout << "Element with index 0 is " << y.get(0) << endl; 55 cout << "Element with index 3 is " << y.get(3) << endl; 56 57 // test erase 58 y.erase(1); 59 cout << "Element 1 erased" << endl; 60 cout << "The list is " << y << endl; 61 y.erase(2); 62 cout << "Element 2 erased" << endl; 63 cout << "The list is " << y << endl; 64 65 cout << "Size of y = " << y.size() << endl; 66 cout << "Capacity of y = " << y.capacity() << endl; 67 if (y.empty()) cout << "y is empty" << endl; 68 else cout << "y is not empty" << endl; 69 70 71 // test copy constructor 72 arrayList<int> w(y); 73 y.erase(0); 74 y.erase(0); 75 cout << "w should be old y, new y has first 2 elements removed" << endl; 76 cout << "w is " << w << endl; 77 cout << "y is " << y << endl; 78 79 // a few more inserts, just for fun 80 y.insert(0, 4); 81 y.insert(0, 5); 82 y.insert(0, 6); 83 y.insert(0, 7); 84 cout << "y is " << y << endl; 85 return 0; 86 }