vector模板类的C++实现
来源:互联网 发布:电脑键盘记录软件 编辑:程序博客网 时间:2024/05/22 02:24
vector的实现 vector.h
/*2017/07/19Liu YK*/#pragma once#include <cassert>#include <iostream>#include <cstdlib>#include <ctime>namespace MYSTL{ typedef int Rank; const int DEFAULT_CAPACITY = 5; template<typename T> class vector { public: friend std::ostream& operator<< (std::ostream& os, const vector<T> &v) { for (Rank i = 0; i < v.m_size; ++i) os << v.m_data[i] << " "; return os; } public: //构造函数和析构函数 vector(int cap = DEFAULT_CAPACITY, int sz = 0, const T v = T()); vector(const T *arr, int n) { copyFrom(arr, 0, n); } vector(const T *arr, Rank lo, Rank hi) { copyFrom(arr, lo, hi); } vector(const vector<T> &v) { copyFrom(v.m_data, 0, v.m_size); } vector(const vector<T> &v, Rank lo, Rank hi) { copyFrom(v.m_data, lo, hi); } ~vector() { delete [] m_data; } vector<T>& operator = (const vector<T> &v); //只读接口 int capacity() const { return m_capacity; } int size() const { return m_size; } bool empty() const { return !m_size; } Rank find(const T &e) const; Rank find(const T &e, Rank lo, Rank hi) const; Rank search(const T &e) const; Rank search(const T &e, Rank lo, Rank hi) const; int disordered() const; //void print() const; //可写访问接口 void push_back(const T &e) { insert(e); } void pop_back() { remove(m_size - 1); } T& operator[](Rank r) { assert(r >= 0 && r < m_size); return m_data[r]; } Rank insert(Rank r, const T &e); Rank insert(const T &e); const T remove(Rank r); int remove(Rank lo, Rank hi); void clear(); int deduplicate(); int uniquify(); void sort(Rank lo, Rank hi); void sort(); protected: void copyFrom(const T *data, Rank lo, Rank hi); void expand(); void shrink(); void bubbleSort(Rank lo, Rank hi); void selectSort(Rank lo, Rank hi); void insertSort(Rank lo, Rank hi); void mergeSort(Rank lo, Rank hi); void merge(Rank lo, Rank mid, Rank hi); Rank binSearch(const T &e, Rank lo, Rank hi) const; Rank binSearch_impl1(const T &e, Rank lo, Rank hi) const;//失败返回-1 Rank binSearch_impl2(const T &e, Rank lo, Rank hi) const;//失败返回-1 Rank binSearch_impl3(const T &e, Rank lo, Rank hi) const;//失败返回不大于e的最大秩 private: int uniquify_impl1(); int uniquify_impl2(); static void swap(T &a, T &b) { T tmp = a; a = b; b = tmp; } protected: Rank m_capacity; Rank m_size; T *m_data; }; template<typename T> vector<T>::vector(int cap = DEFAULT_CAPACITY, int sz = 0, T v = T()) : m_capacity(cap), m_size(sz) { m_data = new T[m_capacity]; for (int i = 0; i < m_size; ++i) m_data[i] = v; } template<typename T> inline vector<T>& vector<T>::operator=(const vector<T>& v) { if (m_data == v.m_data) return *this; delete[] m_data; copyFrom(v.m_data, 0, v.m_size); return *this; } template<typename T> inline Rank vector<T>::find(const T & e) const { return find(e, 0, m_size); } template<typename T> inline Rank vector<T>::find(const T & e, Rank lo, Rank hi) const { assert(lo >= 0 && hi <= m_size && lo < hi); while (--hi >= lo) { if (e == m_data[hi]) return hi; } return -1; } template<typename T> inline Rank vector<T>::search(const T & e) const { return search(e, 0, m_size); } template<typename T> inline Rank vector<T>::search(const T & e, Rank lo, Rank hi) const { return binSearch(e, lo, hi); } template<typename T> inline int vector<T>::disordered() const { int ret = 0; for (int i = 1; i < m_size; ++i) { if (m_data[i - 1] > m_data[i]) ++ret; } return ret; } /*template<typename T> inline void vector<T>::print() const { for (Rank i = 0; i < m_size; ++i) std::cout << m_data[i] << " "; std::cout << std::endl; }*/ template<typename T> inline Rank vector<T>::insert(Rank r, const T & e) { assert(r >= 0 && r <= m_size); expand(); for (Rank i = m_size; i > r; --i) { m_data[i] = m_data[i - 1]; } m_data[r] = e; ++m_size; return r; } template<typename T> inline Rank vector<T>::insert(const T & e) { return insert(m_size, e); } template<typename T> inline const T vector<T>::remove(Rank r) { assert(r >= 0 && r < m_size); T ret = m_data[r]; remove(r, r + 1); return ret; } template<typename T> inline int vector<T>::remove(Rank lo, Rank hi) { assert(lo >= 0 && hi <= m_size && lo < hi); int ret = hi - lo; for (Rank i = hi; i < m_size; ++i) { m_data[lo++] = m_data[i]; } m_size -= ret; shrink(); return ret; } template<typename T> inline void vector<T>::clear() { remove(0, m_size); } template<typename T> inline int vector<T>::deduplicate() { int old_size = m_size; for (int i = 1; i < size();) { if (find(m_data[i], 0, i) != -1) remove(i); else ++i; } return old_size - m_size; } template<typename T> inline int vector<T>::uniquify() { return uniquify_impl2(); } template<typename T> inline void vector<T>::sort(Rank lo, Rank hi) { srand(static_cast<unsigned int> (time(nullptr))); switch (rand() % 5) { case 0 : bubbleSort(lo, hi); break; case 1 : selectSort(lo, hi); break; case 2 : insertSort(lo, hi); break; case 3 : default: mergeSort(lo, hi); break; } } template<typename T> inline void vector<T>::sort() { sort(0, m_size); } template<typename T> inline void vector<T>::expand() { if (m_size == m_capacity) { T *old_data = m_data; if (m_capacity < DEFAULT_CAPACITY) m_capacity = DEFAULT_CAPACITY; m_data = new T[m_capacity <<= 1]; copyFrom(old_data, 0, m_size); delete[] old_data; } } template<typename T> inline void vector<T>::shrink() { if (m_size * 5 < m_capacity) { T *old_data = m_data; m_capacity = (m_capacity / 2 < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : (m_capacity >> 1); m_data = new T[m_capacity]; //copyFrom(old_data, 0, m_size); for (int i = 0; i < m_size; ++i) m_data[i] = old_data[i]; delete[] old_data; } } template<typename T> inline void vector<T>::bubbleSort(Rank lo, Rank hi) { assert(lo >= 0 && hi <= m_size && lo < hi); bool sorted = false; while (!sorted) { sorted = true; for (Rank i = lo + 1; i < hi; ++i) { if (m_data[i - 1] > m_data[i]) { swap(m_data[i - 1], m_data[i]); sorted = false; } } --hi; } } template<typename T> inline void vector<T>::selectSort(Rank lo, Rank hi) { assert(lo >= 0 && hi <= m_size); for (int i = 0; i < m_size; ++i) { T min = m_data[i]; Rank min_idx = i; for (int j = i + 1; j < m_size; ++j) { if (m_data[j] < min) { min = m_data[j]; min_idx = j; } } swap(m_data[min_idx], m_data[i]); } } template<typename T> inline void vector<T>::insertSort(Rank lo, Rank hi) { assert(lo >= 0 && hi <= m_size); for (Rank i = lo + 1; i < hi; ++i) { for (Rank j = i; j > lo; --j) { if (m_data[j] < m_data[j - 1]) swap(m_data[j], m_data[j - 1]); else break; } } } template<typename T> inline void vector<T>::mergeSort(Rank lo, Rank hi) { assert(lo >= 0 && hi <= m_size); if (1 < (hi - lo)) { Rank mid = (hi + lo) >> 1; mergeSort(lo, mid); mergeSort(mid, hi); merge(lo, mid, hi); } } template<typename T> inline void vector<T>::merge(Rank lo, Rank mid, Rank hi) { assert(lo >= 0 && hi <= m_size && lo < mid && mid < hi); T *A = m_data + lo; Rank lb = mid - lo; T *B = new T[lb]; T *C = m_data + mid; Rank lc = hi - mid; for (Rank i = 0; i < lb; ++i) B[i] = A[i]; Rank i = 0; Rank j = 0; Rank k = 0; while ((j < lb) && (k < lc)) { if (B[j] < C[k]) A[i++] = B[j++]; else A[i++] = C[k++]; } if (j >= lb) { while (k < lc) A[i++] = C[k++]; } if (k >= lc) { while (j < lb) A[i++] = C[j++]; } delete[] B; } template<typename T> inline Rank vector<T>::binSearch(const T &e, Rank lo, Rank hi) const { srand(static_cast<unsigned int> (time(nullptr))); switch (2) { case 0 : return binSearch_impl1(e, lo, hi); case 1: return binSearch_impl2(e, lo, hi); case 2: default: return binSearch_impl3(e, lo, hi); } } template<typename T> inline Rank vector<T>::binSearch_impl1(const T & e, Rank lo, Rank hi) const { assert(lo >= 0 && hi <= m_size); while (lo < hi) { Rank mid = (lo + hi) >> 1; if (e == m_data[mid]) return mid; else if (e < m_data[mid]) hi = mid; else lo = mid + 1; } return -1; } template<typename T> inline Rank vector<T>::binSearch_impl2(const T & e, Rank lo, Rank hi) const { assert(lo >= 0 && hi <= m_size); while (1 < (hi - lo)) { Rank mid = (hi + lo) >> 1; if (e < m_data[mid]) hi = mid; else lo = mid; } return (e == m_data[lo]) ? lo : -1; } template<typename T> inline Rank vector<T>::binSearch_impl3(const T & e, Rank lo, Rank hi) const { assert(lo >= 0 && hi <= m_size); while (lo < hi) { Rank mid = (lo + hi) >> 1; (e < m_data[mid]) ? hi = mid : lo = mid + 1; } return --lo; } template<typename T> inline int vector<T>::uniquify_impl1() { int ret = 0; for (Rank i = 0; i < m_size;) { Rank j = i + 1; while (j < m_size) { if (m_data[i] == m_data[j]) ++j; break; } if (i + 1 != j) { ret += remove(i + 1, j); i = j; } else ++i; } shrink(); return ret; } template<typename T> inline int vector<T>::uniquify_impl2() { Rank i = 0; Rank j = 0; while (++j < m_size) { if (m_data[i] != m_data[j]) m_data[++i] = m_data[j]; } m_size = ++i; shrink(); return j - i; } template<typename T> void vector<T>::copyFrom(const T *data, Rank lo, Rank hi) { //m_capacity = ((hi - lo) > DEFAULT_CAPACITY / 2) ? ((hi - lo) << 1) : DEFAULT_CAPACITY; m_data = new T[m_capacity = (hi - lo) << 1]; m_size = 0; while (lo < hi) { m_data[m_size++] = data[lo++]; } }}
测试程序
void test_vector(){ //测试构造函数 int a[] = { 23, 2, 12, 44, -21, 44 }; int sz = sizeof(a) / sizeof(int); MYSTL::vector<int> iv(a, sz); cout << iv << endl; cout << "The capacity is " << iv.capacity() << endl; cout << "The size is " << iv.size() << endl; MYSTL::vector<int> iv1(iv); cout << iv << endl; MYSTL::vector<int> iv11(iv, 0, iv.size() / 2); cout << iv11 << endl; MYSTL::vector<int> iv111(a, 0, sz / 2); cout << iv111 << endl; cout << "-------------------------------------------" << endl; //测试capacity() size() find() 默认构造函数 MYSTL::vector<string> sv(10, 5, "hello"); cout << "The capacity is " << sv.capacity() << endl; cout << "The size is " << sv.size() << endl; for (int i = 0; i < sv.size(); ++i) cout << "iv[" << i << "] = " << sv[i] << endl; sv.deduplicate(); cout << "After deduplicate:" << endl; cout << sv << endl; MYSTL::vector<int> iv2; cout << "The capacity is " << iv2.capacity() << endl; cout << "The size is " << iv2.size() << endl; if (iv2.empty()) cout << "iv2 is empty" << endl; cout << "---------------------------------------" << endl; //测试写访问操作 for (int i = 0; i < 20; ++i) iv2.insert(i); cout << "12 is in Rank " << iv2.find(12) << endl; cout << iv2 << endl; cout << "After insert: " << endl; cout << "The capacity is " << iv2.capacity() << endl; cout << "The size is " << iv2.size() << endl; iv2.insert(10, 100); cout << "After insert: " << endl; cout << iv2 << endl; cout << "After expand: " << endl; cout << "The capacity is " << iv2.capacity() << endl; cout << "The size is " << iv2.size() << endl; iv2.remove(0); cout << "After remove Rank 0:" << endl; cout << iv2 << endl; cout << "The size is " << iv2.size() << endl; iv2.remove(3, iv2.size()); cout << "After remove between Rank 3 to end:" << endl; cout << iv2 << endl; cout << "The capacity is " << iv2.capacity() << endl; cout << "The size is " << iv2.size() << endl; iv2 = iv; cout << "After assign, iv2 is:" << endl; cout << iv2 << endl; cout << "The capacity is " << iv2.capacity() << endl; cout << "The size is " << iv2.size() << endl; MYSTL::vector<int> iv3; cout << "The capacity is " << iv3.capacity() << endl; cout << "The size is " << iv3.size() << endl; for (int i = 0; i < 100; ++i) iv3.push_back(i); cout << "iv3 is " << endl; cout << iv3 << endl; cout << "The capacity is " << iv3.capacity() << endl; cout << "The size is " << iv3.size() << endl; for (int i = 0; i < 100; ++i) iv3.pop_back(); cout << "iv3 is " << endl; cout << iv3 << endl; cout << "The capacity is " << iv3.capacity() << endl; cout << "The size is " << iv3.size() << endl; //测试有序向量 int a1[] = { 23, 32, 23, 1, 21, -3, 2, 23, -3, 1, 23 }; int sz1 = sizeof(a1) / sizeof(int); MYSTL::vector<int> iv4(a1, sz1); MYSTL::vector<int> iv5(iv4); cout << "Before sort:" << endl; cout << iv4 << endl; cout << "reverse pair is " << iv4.disordered() << endl; iv4.sort(); cout << "After sort:" << endl; cout << iv4 << endl; cout << "reverse pair is " << iv4.disordered() << endl; cout << "iv5 is " << endl; cout << iv5 << endl; iv5.deduplicate(); cout << "After deduplicate" << endl; cout << iv5 << endl; iv5.sort(); iv5.uniquify(); cout << "After uniquify" << endl; cout << iv5 << endl; cout << iv5.search(20) << endl; //测试clear iv5.clear(); cout << "Is empty? " << iv5.empty() << endl; }
阅读全文
1 0
- 【c++】模板实现动态Vector
- c++vector模板类
- c++vector模板类
- vector模板类的C++实现
- 有关模板类----实现Vector的类模板
- C++:STL模板类vector
- C模板实现STL容器中的vector
- 【c++】模板实现vector和list
- 【C++】用模板实现顺序表Vector
- vector的实现【C++】
- C++模板类实现Vector
- vector相关的模板类函数声明与实现
- C++,vector模板类的问题? std::vector<PointT, Eigen::aligned_allocator<PointT> > points;
- C++向量Vector模板的实现
- vector模板类的用法
- 类模板模拟实现STL中Vector
- 模板实现Vector
- vector类的实现
- 前端工具_ps_01
- 数据结构与算法专题之线性表——链表(二)双向链表
- 169. Majority Element
- 菜鸟心历之路(1)
- C++多态理解及多态对象模型探索
- vector模板类的C++实现
- 关于动态链库与动态链接库的心得
- 欢迎使用CSDN-markdown编辑器
- spring bean配置之集合属性
- hdu3333(线段树求不同数字之和)
- 51nod 1013 3的幂的和
- 数据结构与算法专题之线性表——链表(三)循环链表
- vb.net 教程 12-2 HtmlDocument类 3
- Java反射机制(一)