码迷,mamicode.com
首页 > 编程语言 > 详细

[C++] MyList<T>

时间:2015-06-12 13:17:03      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:

完成作业型。。。保证无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;
}

 

[C++] MyList<T>

标签:

原文地址:http://www.cnblogs.com/catchyrime/p/4571375.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!