C++模拟vector

// 模拟vector
#include<cstdio>
#include<iostream>
#include<cmath>
#include"Fibonacci.h"
#define DEFAULT_CAPACITY 10
using namespace std;
using Rank = int;                            //typedef int Rank ,与using相比,差了点

template<typename T>
struct func_add {             // 定义函数对象
	int add_num=5;
	func_add(int num) :add_num(num) {}    // 构造函数,注意与java区分
	func_add(){}
	void operator()(T& e) {
		e += add_num;
	}
};

template<typename T>
class my_vector
{
private:
	Rank _size; int capacity; T* _elem;

// 内部操作
public:
	void copyFrom(T const* Arr,Rank low,Rank high);
	void expand();
	void insert(Rank r, T const& data);    // 在秩为r的地方插入data
	int remove(Rank low, Rank high);       //删除[low,high)的元素
	T remove(Rank r);                      //删除秩为r的元素,返回该元素原值
	Rank find(T const& e, Rank low, Rank high);  //无序向量的查找,所谓无序,即只支持==操作,不支持“>,<”操作
												//命中多个元素返回秩最大的
	//void traverse(void(*visit)(T& e,int value),int Value);    // 遍历向量,对每个元素实行visit操作,visit是一个函数指针
	template<typename FunClass>void traverse(FunClass& func);  // 模板类的模板函数
	int deduplicate();       // 返回剔了多少个重复元素
	int uniquify();          // 有序向量的唯一化
	int disordered();        // 返回多少个相邻的逆序对

	void Sort(Rank low, Rank high);         //[low,high]闭区间
	void swap(T& a, T& b);
	void bubble_sort(Rank low, Rank high);
	void merge_sort(Rank low, Rank high);

	Rank Search(T const& e, Rank low, Rank high);   // [low,high)开区间
	Rank bi_search(T const& e, Rank low, Rank high);
	Rank fib_search(T const& e, Rank low, Rank high);
	my_vector& operator=(my_vector const& v);
	T& operator [](Rank r);               // 数组要r为下标才可以访问,故函数参数是r。可作为左值eg:v[r]=(T)...
	const T& operator [](Rank r)const;  // 仅可作为右值引用,eg:T a=v[1]+v[3],因为左值要可以修改,不可为const

// 对外接口
public:
	// 构造函数
	/*vector()
	{
		r = 0, _size = 0, capacity = DEFAULT_CAPACITY;
	}*/   // 这样写不太行
	
	// 注意一个问题:this关键字,复值的时候别弄错了
	my_vector(Rank size=0,int Capacity=DEFAULT_CAPACITY,T e=0)  //带默认参数的构造函数,准备把向量全部初始化为0
	{
		this->_size = size;

		// 保证capacity>=DEFAULT_CAPACITY
		_elem = new T[this->capacity = Capacity > DEFAULT_CAPACITY ? Capacity : DEFAULT_CAPACITY]; 
		for (int i = 0; i < this->capacity; ++i) 
		{ 
			_elem[i] = e; 
		}
	}

	// 通过初始化调用构造函数,复制一部分
	my_vector(my_vector<T> const& v, Rank low, Rank high)
	{
		//copyFrom(v, low, high);   你这就完全搞错了,vector v是一个结构体,传递参数要注意呀!!!
		copyFrom(v._elem, low, high);
	}

	// 复制整体eg: vector<int> v1;     vector<int> v2=v1(此处便是调用下面的构造函数)
	my_vector(my_vector<T> const& v)
	{
		copyFrom(v._elem, 0, v._size);
	}


	// 析构函数
	~my_vector()
	{
		//delete _elem[];
		delete[] _elem;
	}


	// 定义接口
	void show()
	{
		for (int i = 0; i < _size; ++i)
			cout << _elem[i] << " ";
		cout << endl;
	}
	int size() { return _size; }
};

template<class T> void my_vector<T>::copyFrom(T const* Arr, Rank low, Rank high)
{
	_elem = new T[ capacity=max((high - low)<<1,DEFAULT_CAPACITY)];   // 为什么要*2,见扩容部分,且要把capacity加进去
	                                                                  // 否则capacity仍然是0
	_size = 0;
	while (low < high)
	{
		_elem[_size++] = Arr[low++];     // 不得不说这样写是真NB,虽然Arr[high]被复制了,但是size并不承认Arr[high]
	}
}
// 采用倍增式扩容,注意分摊复杂度
template<class T> void my_vector<T>::expand()
{
	if (_size < capacity) return;       // 此处不可以为=
	if (capacity < DEFAULT_CAPACITY)
		capacity = DEFAULT_CAPACITY;
	T* old_elem = _elem;
	_elem = new T[capacity <<= 1];
	for (int i = 0; i < _size; ++i)
	{
		_elem[i] = old_elem[i];           // 复制原有的old序列
	}
	//delete old_elem;                    // 这是一个数组,要用delete []
	/*printf("\n[]*size:%d capacity:%d after expend->[]*size:%d capacity:%d", \
		 size, capacity / 2,  size, capacity);*/
	// 此处为printf的局限性
	cout << "capacity:" << capacity / 2 << " after expand->" << "capacity:" << capacity << endl;
	delete []old_elem;
}

// 运算符重载
template<class T> my_vector<T>& my_vector<T>::operator=(const my_vector<T>& v)
{
	// 自身赋值问题
	if (&v == this)      // 直接比较地址
		return *this;
	// 多次赋值内存管理问题
	if (this->_elem != NULL)
		delete[] _elem;
	this->_elem = new T[v.capacity];
	for (int i = 0; i < v._size; ++i)
	{
		this->_elem[this->_size++] = v->_elem[i];
	}
	return *this;
}
template<class T> T& my_vector<T>::operator[](Rank r)
{
	return this->_elem[r];
}
//template<class T> const T& my_vector<T>::operator[](Rank r)   与上面的那个operator[]重载类型不兼容!!!
template<class T> const T& my_vector<T>::operator[](Rank r)const
{
	return this->_elem[r];
}


template<class T> void my_vector<T>::insert(Rank r, T const& data)
{
	expand();
	for (int i = _size; i > r; i--)                   // i==r,就直接往后插
	{
		_elem[i] = _elem[i - 1];
	}
	_elem[r] = data;
	_size++;
}
//template<class T> T my_vector<T>::remove(Rank r)
//{
//	T temp = _elem[r];
//	for (int i = r; i < _size-1; ++i) { _elem[i] = _elem[i + 1]; }
//	_size--;
//	return temp;
//}
template<class T> T my_vector<T>::remove(Rank r)
{
	T temp = _elem[r];
	remove(r, r + 1);
	return temp;
}
// 返回被删除的元素的个数
template<class T> int my_vector<T>::remove(Rank low, Rank high)
{
	if (low == high)
		return 0;  //不删
	while (high<_size)
	{
		_elem[low++] = _elem[high++];
	}
	_size -= (high - low);
	return high - low;
}
//输入敏感性算法:best O(1)  worst O(n)
template<class T> Rank my_vector<T>::find(T const& e, Rank low, Rank high)
{
	// 从右往左找:因为命中多个元素返回秩最大的
	while (low < high-- && _elem[high] != e);                 //about low<high--<===>先low<high? 后high--
	return high;
}

template<class T>int my_vector<T>::deduplicate()
{
	/*int old_size = _size;
	for (int i = 1; i < _size; ++i)
	{
		Rank index = find(_elem[i], 0, i);
		if (index >= 0)
			remove(index);
	}
	return old_size - _size;*/
	// 注意!!!   此种做法会改变vector内部数据,导致index失效
	int old_size = _size;
	int i = 1;
	while (i < _size)
	{
		Rank index = find(_elem[i], 0, i);
		if (index >= 0)
			remove(i);          // means删除后来重复的元素,保留前面的
								// remove(index) means 把前面重复的去掉,保留后面新进来的元素
		else
			i++;
	}
	return old_size - _size;
}
template<typename T> int my_vector<T>::uniquify()
{
	//int cnt = 0;     // cnt means 重复几次元素     eg:2 2 2 表示重复两次元素
	//int i = 0;
	//int old_size = _size;
	//while (i < _size)
	//{
	//	T temp = _elem[i];
	//	for (int j = i+1; j < _size&&_elem[j] == temp; ++j)
	//	{
	//		cnt++;
	//	}
	//	if (cnt > 0)
	//	{
	//		remove(i + 1, i + 1 + cnt);
	//		cnt = 0;
	//	}
	//	i++;
	//}
	//return old_size - _size;               // 此类复杂度仍无实质改变,对于1,1,2,2,3,3,4,4序列,仍为O(n^2)

	// 对算法进行反思:
	// 造成这种退化情况,仍然是remove 操作一次只删除一个元素
	// 改进算法如下:
	int i = 0, j = 0; int old_size = _size;
	while (++j < _size)
		if (_elem[i] != _elem[j]) _elem[++i] = _elem[j];
	remove(i + 1, j);
	return _size - old_size;
}
template<typename T> int my_vector<T>::disordered()
{
	int cnt = 0;                            // 初始逆序对的值设为0
	for (int i = 1; i < _size; ++i)
	{
		if (_elem[i - 1] != _elem[i])
			cnt++;
	}
	return cnt;
}
//template<typename T>void increase_all_elem(T&e,int value )
//{
//	e += value;
//}
//template<typename T>void my_vector<T>::traverse(void(*increase_all_elem)(T& e,int value),int Value)
//{
//	for (int i = 0; i < _size; ++i)
//	{
//		increase_all_elem(_elem[i],Value);
//	}
//}
// 这样写好麻烦,并且效率不高
// 改进后的版本
template<typename T> template<typename FunClass>
void my_vector<T>::traverse(FunClass& func_add) {
	for (int i = 0; i < _size; ++i)
		func_add(_elem[i]);
}
template<typename T> void my_vector<T>::Sort(Rank low, Rank high)
{
	switch (rand() % 1+1) {
	case 1:
		bubble_sort( low,  high);
		break;
	case 2:
		merge_sort( low,  high);
		break;
	}
}
template<typename T>void my_vector<T>:: swap(T& a, T& b)
{
	//T temp = new T;
	T temp;
	temp = a;
	a = b;
	b = temp;
}
template<typename T>void my_vector<T>::bubble_sort(Rank low, Rank high)  //[low,high]
{
	Rank last = high;
	for (Rank i = last; i >low;)
	{
		for (Rank j = (last=low)+1; j <= i; ++j)    // // 假设每次向量是有序的,即last=0
			if (_elem[j - 1] > _elem[j]) {
				swap(_elem[j - 1], _elem[j]);
				last = j - 1;
			}
		i = last;    // last(包含last)之后必定有序
	}
}
template<typename T> void merge(T* elem, Rank low, Rank mid, Rank high)
{
	T* arr_A = new T[mid - low + 1];
	int i = low;
	for (int cnt=0; cnt <= mid - low + 1; ++cnt)
	{
		arr_A[cnt] = elem[i++];
	}
	i = low;
	int j = mid + 1, k = low;
	while (i <= mid && j <= high)    // 双方均未越界
	{
		elem[k++] = arr_A[i] > elem[j] ? elem[j++] : arr_A[i++];
	}
	while (i <= mid)              // 后面的数组越界,直接拷贝前面的即可
	{
		elem[k++] = arr_A[i++];
	}

}
template<typename T> void my_vector<T>::merge_sort(Rank low, Rank high)
{
	// low<=high Error:核心是单个元素有序
	if ((high-low)>1)
	{
		Rank mid = (low + high) >>1;
		merge_sort(low, mid);
		merge_sort(mid+1, high);
		merge(_elem, low, mid, high);
	}
}

template<typename T> Rank my_vector<T>::Search(T const& e, Rank low, Rank high)
{
	switch (rand() % 2 + 1) {
	case 1:
		bi_search( e, low,  high);
		break;
	case 2:
		fib_search( e,  low,  high);
		break;
	}
}
template<typename T> Rank my_vector<T>::bi_search(T const& e, Rank low, Rank high)
{
	while (low < high)
	{
		Rank mid = (low + high) >> 1;
		e < _elem[mid] ? high = mid : low = mid + 1;
	}
	return --low;      // 区间缩短至0,arr[high=low]为大于e的最小元素
}
template<typename T> Rank my_vector<T>::fib_search(T const& e, Rank low, Rank high)
{
	for (Fib fib(high - low);high > low;)
	{
		// 找出黄金分割点
		int mid;
		while (fib.get() > (high - low)) { mid = fib.pre()+low; }
		if (e < _elem[mid])
			high = mid;
		else if (_elem[mid] < e)
			low = mid + 1;
		else
			return mid;
	}
	return -1;
}
int main()
{
	my_vector<int> v1(6, 3, 1);
	my_vector<int> v2 = v1;
	
	func_add<int> funAdd(5);
	v2.traverse(funAdd);
	v2.show();
	// v2.traverse(new func_add<int>(9)); // Error:Simple reference cannot bind to temp var(变量)
	my_vector<int> v3;
	for (int i = 0; i < 10; ++i) { v3.insert(rand() % 10, rand() % 20); }
	v3.show();
	v3.Sort(0, v3.size() - 1);
	v3.show();
	v3.insert(v3.bi_search(6,0,v3.size()) + 1, 6);
	v3.show();
	
}












 番外篇:对C++基础知识的一些补充
01.函数对象与函数指针(传参问题可是折磨我等)

void add5(int& value)
{
	value += 5;
}
class fun_add
{
private:
	int num;
public:
	fun_add(int number):num(number){}
	void operator()(int add_num)
	{
		num += add_num;
	}
};
template<typename Func>
void add(int* arr, int n, Func func)
{
	for (int i = 0; i < n; ++i)
	{
		func(arr[i]);
	}
}
int main()
{
	int array[10] = { 1,4,7,2 };
	add(array, 10, add5);                 // 传递过后func是void(*)(int&)类型,即函数指针
	add<void(*)(int&)>(array, 10, add5);
										// func是fun_add类型,以上均属于隐式的实例化函数模板
	add(array, 10, fun_add(5));  //add<func_add(5)>(array, 10, fun_add(5)) Error:显示实例化是传class类型而不是对象      
	add<fun_add>(array, 10, fun_add(5)); 
										 //add<void(*)(int&)>...为显式
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值