标签:
完成作业型。。。保证无bug,完全没考虑效率。
#include <iostream> using namespace std; #define DEBUG #ifdef DEBUG #define ASSERT(expr) { if (!(expr)) { cout << "=============== ASSERT(" << #expr << ") failed at line " << __LINE__ << " in function " << __FUNCTION__ << "() " << endl; throw(0); } } #else #define ASSERT(expr) #endif template<typename T> class MyList { private: // copy ‘cnt‘ elements from ‘src‘ to ‘dest‘ // ignore if (cnt == 0) static void __copy(T* dest, const T* src, int cnt) { ASSERT(cnt >= 0); if (!cnt || src == dest) return; if (src < dest) { for (int i = cnt-1; i >= 0; --i) dest[i] = src[i]; } else { for (int i = 0; i < cnt; ++i) dest[i] = src[i]; } } // reverse [start, end] static void __reverse(T* start, T* end) { ASSERT(start <= end); for (int i = 0; i <= (end-start)/2; ++i) { T tmp = start[i]; start[i] = end[-i]; end[-i] = tmp; } } // qsort [start, end] // increasingly if (less == true), decreasingly otherwise static void __qsort(T* start_elem, T* end_elem, bool less) { T *st = start_elem, *ed = end_elem; if (st >= ed) return; const T pivot = *st; if (less) { while (st < ed) { while (st < ed && *ed >= pivot) --ed; *st = *ed; while (st < ed && *st <= pivot) ++st; *ed = *st; } } else { while (st < ed) { while (st < ed && *ed <= pivot) --ed; *st = *ed; while (st < ed && *st >= pivot) ++st; *ed = *st; } } *st = pivot; __qsort(start_elem, st-1, less); __qsort(ed+1, end_elem, less); } // deep clone the list form ‘src‘ to ‘dest‘ static void __clone(MyList* dest, const MyList* src) { ASSERT(dest && src && dest != src); dest->zero(); if (! src->m_Size) return; // ‘src‘ is empty dest->initialize(src->m_Size); __copy(dest->m_List, src->m_List, src->m_Size); } private: int m_Size; // current element count int m_MaxSize; // max element count T* m_List; // buffer private: // allocate memory for 16 elements if (m_List == NULL) // double m_List otherwise void double_space(void) { ASSERT(m_Size == m_MaxSize); if (! m_MaxSize) { // not allocated before ASSERT(m_List == NULL); m_MaxSize = 16; m_List = new T[m_MaxSize]; return; } ASSERT(m_List != NULL); T* newList = new T[m_MaxSize*2]; __copy(newList, m_List, m_Size); delete[] m_List; m_List = newList; m_MaxSize *= 2; } // initialize this with a specific size void initialize(int size) { ASSERT(size > 0); this->m_Size = this->m_MaxSize = size; this->m_List = new T[size]; } // set ‘this‘ with all-zero void zero() { m_Size = m_MaxSize = 0; m_List = (T*)NULL; } public: // constructor: a new empty list MyList() { this->zero(); } // constructor: with ‘item‘ repeating ‘num‘ times MyList(int num, const T& item) { this->zero(); // ASSERT(num >= 0) if (num <= 0) return; this->initialize(num); for (int i = 0; i < num; ++i) { m_List[i] = item; } return; } // copy constructor: deep clone from a list // attention: avoid cloning from itself MyList(const MyList& lst) { // ASSERT(this != &lst); if (this != &lst) { __clone(this, &lst); } } // constructor: with first ‘len‘ elements in ‘arr‘ MyList(T* arr, int len) { this->zero(); // ASSERT(len >= 0); if (len <= 0) return; ASSERT(arr != NULL); this->initialize(len); __copy(m_List, arr, len); } // destroctor: free the buffer is allcated before ~MyList() { if (! m_List) { ASSERT(m_Size == 0 && m_MaxSize == 0); return; } delete[] m_List; this->zero(); } // insert ‘item‘ at the position of ‘index‘ void insert(int index, const T& item) { // ‘push()‘ when (index == m_Size) ASSERT(index >= 0 && index <= m_Size); if (m_Size == m_MaxSize) this->double_space(); // __copy: ignored if (m_Size == index) __copy(m_List+index+1, m_List+index, m_Size-index); m_List[index] = item; ++m_Size; } // clear current list void clean() { m_Size = 0; } // push ‘item‘ to end of the list void push(const T& item) { this->insert(m_Size, item); // insert: ‘index‘ = m_Size } // pop from end of the list T pop() { ASSERT(m_Size > 0); return m_List[--m_Size]; } // get element count int get_size() const { return m_Size; } // erase elements indexed [start, end] void erase(int start, int end) { ASSERT(start >= 0 && end < m_Size); ASSERT(start <= end); // __copy: ignore if (end == m_Size-1) __copy(m_List+start, m_List+end+1, m_Size-1-end); m_Size -= end-start+1; } // get the reference of element indexed ‘index‘ T& operator [](int index) const { ASSERT(index >= 0 && index < m_Size); return m_List[index]; } // get the element indexed ‘index‘ T get_item(int index) const { ASSERT(index >= 0 && index < m_Size); return m_List[index]; } // pick elements index [start, end] to form a new list // if (end == -1), then pick from ‘start‘ to the last element. MyList get_item(int start, int end) const { // specially treat when (end = -1) if (end == -1) { end = m_Size-1; } // ASSERT(start <= end && start >= 0 && end < m_Size); if (start <= end && start >= 0 && end < m_Size) { // if this is empty, 0 <= start <= end < m_Size = 0 is impossible return MyList(m_List+start, end-start+1); } return MyList(); // empty } // count the element ‘item‘ in the list int count(const T& item) const { int ret = 0; for (int i = 0; i < m_Size; ++i) { if (m_List[i] == item) ++ret; } return ret; } // remove the element ‘item‘ in the list (at the first present) void remove(const T& item) { for (int i = 0; i < m_Size; ++i) { if (m_List[i] == item) { this->erase(i, i); return; } } } // like copy construtor, deep clone from ‘lst‘ // attention: avoid cloning from itself MyList& operator =(const MyList& lst) { if (this != &lst) { // a = a __clone(this, &lst); } return *this; } // add the element ‘item‘ to the end of this list MyList& operator +=(const T& item) { this->push(item); return *this; } // add the list ‘lst‘ to the end of this list MyList& operator +=(const MyList& lst) { MyList tmp = lst; for (int i = 0; i < tmp.m_Size; ++i) { this->push(tmp.m_List[i]); } return *this; } // sort current list // increasingly if (less == true), decreasingly otherwise void sort(bool less = true) { if (! m_Size) return; ASSERT(m_List != NULL); __qsort(m_List, m_List + m_Size-1, less); } // reverse current list void reverse() { if (! m_Size) return; ASSERT(m_List != NULL); __reverse(m_List, m_List + m_Size-1); } // merge two list to a new list template<typename _T> friend MyList<_T> operator +(const MyList<_T>&, const MyList<_T>&); // merge a list and an element to a new list template<typename _T> friend MyList<_T> operator +(const MyList<_T>&, const _T&); // output the list to an ostream template<typename _T> friend ostream& operator <<(ostream&, const MyList<_T>&); }; template<typename T> MyList<T> operator +(const MyList<T>& lst1, const MyList<T>& lst2) { MyList<T> ret = lst1; ret += lst2; return ret; } template<typename T> MyList<T> operator +(const MyList<T>& lst, const T& item) { MyList<T> ret = lst; ret += item; return ret; } template<typename T> ostream& operator <<(ostream& os, const MyList<T>& lst) { os << "["; for (int i = 0; i < lst.m_Size; ++i) { if (i) os << ", "; os << lst.m_List[i]; } os << "]"; return os; } int main() { MyList<int> a, b; for(int i = 0; i < 5; ++i) { a.push(i); } // a = [0, 1, 2, 3, 4] a[3] = 15; // a = [0, 1, 2, 15, 4] a.sort(); // a = [0, 1, 2, 4, 15] a.reverse(); // a = [15, 4, 2, 1, 0] a += 12; // a = [15, 4, 2, 1, 0, 12] for(int i = 0; i < a.get_size(); ++i) { cout << a[i] << endl; } b = a.get_item(4, -3); // b = [] *若start > end,返回空数组 b = a.get_item(3, -1); // b = [1, 0, 12] a += b; // a = [15, 4, 2, 1, 0, 12, 1, 0, 12] for(int i = 0; i < a.get_size(); ++i) cout << a.get_item(i) << endl; cout << a.count(5) << endl; b.clean(); // b = [] cout << b.get_size() << endl; a.erase(2, 5); // a = [15, 4, 1, 0, 12] b = a + a; // b = [15, 4, 1, 0, 12, 15, 4, 1, 0, 12] b.insert(3, 116); // b = [15, 4, 1, 116, 0, 12, 15, 4, 1, 0, 12] b.remove(4); // b = [15, 1, 116, 0, 12, 15, 4, 1, 0, 12] cout << b << endl; MyList<double> c(10, 3.14); for(int i = 0; i < 100; ++i) c.push(1.1 * i); cout << c.get_item(100, 105) << endl; return 0; }
标签:
原文地址:http://www.cnblogs.com/catchyrime/p/4571375.html