DSA学习笔记——向量3(常规向量)

1、重载操作符[]

template <typename T>
T& Vector<T>::operator[](Rank r)const{
	return _elem[r];
}

2、置乱器

注意置乱算法和区间置乱接口的区别,前者通过重载操作符[]使用秩间接访问向量元素,后者通过下标(地址)直接访问内部数组的元素。

//随机置乱向量,使各元素等概率出现于各位置
template <typename T>
void permute(Vector<T>& V){
	for(int i = V.size(); i > 0; i --){
		swap(V[i-1], V[rand() % i]);
	}
}
//区间置乱接口
template <typename T>
void Vector<T>::unsort(Rank lo, Rank hi){
	T* V = _elem + lo;
	for(Rank i = hi - lo; i > 0; i --)
		swap(V[i-1],V[rand() % i]);
}

3、无序查找

template <typename T>
Rank Vector<T>::find(T const& e, Rank lo, Rank hi)const{
	while((lo < hi--) && (e != _elem[hi]));
	return hi;
}

4、插入

template <typename T>
Rank Vector<T>::insert(Rank r, T const& e){
	expand();
	for(int i = _size; i > r; i --) _elem[i] = _elem[i-1];
		_elem[r] = e;
	_size ++;
	return r;
}

5、删除

//区间删除
template <typename T>
int Vector<T>::remove(Rank lo, Rank hi){
	if(lo == hi) return 0;
	while(hi < _size) _elem[lo++] = _elem[hi++];
	_size = lo;
	shrink();
	return hi - lo;
}
//单元素删除
template <typename T>
T Vector<T>::remove(Rank r){
	T e = _elem[r];
	remove(r, r+1);
	return e;
}

6、唯一化

template <typename T>
int Vector<T>::deduplicate(){
	int oldSize = _size;
	Rank i = 1;
	while(i < _size)
		(find(_elem[i], 0, i) < 0) ? i++ : remove(i);
	return oldSize - _size;
}

7、遍历

函数对象因将类对象的操作符()重载后在形式上等效于一个函数接口而得名,相比于函数指针机制,前者功能更强,适用范围更广,比如函数对象的形式支持对向量元素的关联修改(可以有成员变量存储一些状态)。

//借助函数指针机制
template <typename T>
void Vector<T>::traverse(void (*visit)(T&)){
	for(int i = 0; i < _size; i++)
		visit(_elem[i]);
}
//借助函数对象机制
template <typename T> template <typename VST>
void Vector<T>::traverse(VST& visit){
	for(int i = 0; i < _size; i++)
		visit(_elem[i]);
}

函数对象形式遍历具体操作举例(假设T可直接递增或已重载“++”操作)

template <typename T>
struct Increase{
	virtual void operator()(T& e){e++;}
}

template <typename T> void increase(Vector<T>& V){
	V.traverse(Increase<T>());
}
发布了38 篇原创文章 · 获赞 0 · 访问量 2016

猜你喜欢

转载自blog.csdn.net/Nemoosi/article/details/104667608
今日推荐