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>());
}