STL标准模板库 之 vector

一、特点

1、内存连续;
2、支持随机访问;
3、随机访问效率高 ;
4、插入与删除:只有在末尾插入和删除的效率比较高(常量时间复杂度O(1)),在容器中查找或者在中间和前面插入或删除时,呈线性复杂度O(n)。

二、构造函数

vector();//空构造
vector( size_type num, const TYPE &val );//通过val拷贝构造num个对象存储到容器中
vector( const vector &from );//构造构造
vector( input_iterator start, input_iterator end );//把[start,end)区间所有的迭代器所指向的元素通过拷贝构造添加到容器中

三、支持的运算符

== != >= <= > < []

#include 
#include 
using namespace std;

template
void print(IT beg,IT end){
	for(IT it = beg;it != end; ++it){
		cout << *it << " ";	
	}	
	cout << endl;
}

class A{
public:
	int x;
public:
	A(){
		cout << "A()" << endl;
		x = 0;
	}
	A(int x){
		cout << "A(int x)" << endl;
		this->x = x;
	}
	A(const A& a){
		cout << "A(const A& a)" << endl;
		this->x = a.x;
	}
	bool operator==(const A& a)const{
		return x == a.x;	
	}
	friend ostream& operator<<(ostream& os,const A& a){
		return os << a.x;
	}
};

int main(){
	vector v(10,119);
	cout << v.size() << endl;
	print(v.begin(),v.end());
	
	vector va(10,A(19));
	print(va.begin(),va.end());

	vector vv;
	A a(10);
	vv.push_back(a);//放到容器中是a的拷贝构造之后的副本对象
	a.x = 100;
	cout << *vv.begin() << endl;
	int arr[10] = {0,1,2,3,4,5,6,7,7,8};
	vector vi(arr,arr+10);//[arr,arr+10) 区间所有的元素
	cout << vi.size() << endl;
	print(arr,arr+10);
	vector v2(v.begin(),v.end());
	cout << v2.size() << endl;
	print(v2.begin(),v2.end());
	cout << boolalpha << (v==v2) << endl;
	vector va1(10,A(1));
	vector va2(10,A(1));
	cout << boolalpha << (va1==va2) << endl;
	cout << boolalpha << (va1 != va2) << endl;
	va2[5] = A(20);
	return 0;	
}

四、关于大小的函数

size() / capacity() / reserve() / resize() / clear()

size()

返回容器中元素的个数;

capacity()

返回vector所能容纳的元素数量(在不重新分配内存的情况下);

注意:

vector为了能够提高效率,可以事先进行预分配内存,即容器容量;
vector支持容量自增长、自回收 , 容量大小不固定 ;
当够时自动扩容(默认扩充1倍) 不会自动缩小容量。

reserve()

可以扩充预留的内存(单位元素大小) 但是不会回收内存,只是单纯分配内存 并不会调用构造函数进行构造。

resize()

可以改变容器中元素的数量
如果扩大 ,会调用无参构造函数构造一个对象 ,然后通过该对象拷贝构造对象存储到容器中;
如果缩小 ,多出的元素会调用析构函数进行释放。

#include 
#include 
using namespace std;

int main(){
	vector v;
	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;
	//v.reserve(10);
	v.push_back(1);
	v.push_back(1);
	v.push_back(1);
	v.push_back(1);
	v.push_back(1);
	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;	
	for(int i=0;i<100;i++){
		v.push_back(i);	
	}
	
	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;
	for(int i=0;i<100;i++){
		v.pop_back();	
	}
	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;
	v.reserve(8);
	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;
	v.reserve(256);
	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;
	v.resize(100);
	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;
	v.resize(20);
	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;
	return 0;	
}

clear()

清空容器中的元素 会调用析构函数。

#include 
#include 
using namespace std;

class A{
public:
	A(){
		cout << "A()" << endl;	
	}
	A(const A& a){
		cout << "A(const A& a)" << endl;
	}
	~A(){
		cout << "~A()" << endl;	
	}
};

int main(){
	vector v;
	v.reserve(10);
	v.resize(5);//扩充  构造一个无参对象	
	cout << "--------------" << endl;
	v.reserve(1);
	v.resize(2);
	cout << "--------------" << endl;
	v.clear();
	cout << v.size() << endl;
	cout << v.capacity() << endl;
	cout << "--------------" << endl;
	return 0;	
}

五、empty

作用:

判断是否为空

六、获得元素

at

如果越界,则抛出异常 out_of_range

[ ]

即使越界访问不一定抛出异常 ,所以很危险

#include 
#include 
#include 
using namespace std;

int main(){
	vector v(10,119);
	cout << v[1] << endl;
	cout << v.at(1) << endl;
	cout << v[11] << endl;//危险 即使越界也不一定报错
	try{
		cout << v.at(10) << endl;//at  超出范围抛出异常
	}catch(out_of_range& e){
		cout << "越界访问" << endl;	
	}
	return 0;	
}

七、添加元素

push_back() 和 insert
不提供push_front的原因是这样效率低,所以不希望频繁地在前面插入元素
iterator insert( iterator loc, const TYPE &val );
void insert( iterator loc, size_type num, const TYPE &val );
void insert( iterator loc, input_iterator start, input_iterator end );

八、删除元素

erase 和 pop_back()
iterator erase( iterator loc );
iterator erase( iterator start, iterator end );

如果迭代器发生变化 需要重新获取

九、迭代器 iterator

const_iterator

常迭代器 常对象只能用常迭代器

正向迭代器

++往后 --往前

begin()

函数返回一个指向当前vector起始元素的迭代器

end()

函数返回一个指向当前vector末尾元素的下一位置的迭代器.
注意:如果你要访问末尾元素,需要先将此迭代器自减1.

逆向迭代器

++ 往前 --往后

rbegin()

rbegin函数返回指向当前vector末尾的逆迭代器

rend()

返回指向当前vector起始位置的逆迭代器

十、交换

swap( )

#include 
#include 
#include 
using namespace std;

template
void print(IT beg,IT end){
	for(IT it = beg;it != end; ++it){
		cout << *it << " ";	
	}	
	cout << endl;
}

int main(){
	vector v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.insert(v.begin(),10);
	v.insert(v.end(),20);
	print(v.begin(),v.end());
	v.insert(v.begin(),10,0);
	print(v.begin(),v.end());

	int arr[10] = {11,21,32,45,66,77,54,89,98,100};
	v.insert(v.begin()+3,arr,arr+10);
	print(v.begin(),v.end());
	
	vector::iterator it = v.begin();
	for(;it != v.end(); it++){
		if(*it == 0){
			it = v.erase(it);	
			--it;
		}	
	}
	print(v.begin(),v.end());
	print(v.rbegin(),v.rend());

	const vector l(v);//常对象
	vector::const_iterator itt = l.begin();
	for(;itt != l.end(); ++itt){
		cout << *itt << " ";	
	}
	cout << endl;
	vector v1(2,100);

	v.swap(v1);
	print(v.begin(),v.end());
	print(v1.begin(),v1.end());
	//sort(v1.rbegin(),v1.rend());
	sort(v1.begin(),v1.end());
	print(v1.begin(),v1.end());
	return 0;	
}

十一、排序 和 查找

	#include 
	template
	void sort(IT beg,IT end);//直接用 < 进行比较    自定义类型如果要默认的排序得重载<
	void sort(IT beg,IT end,函数对象);//  XXX()
	
	class XXX{
	public:
		int operator()(const T& t1,const T& t2)(){
		
		}
	};
	
	find(IT beg,IT end,const T& data)   返回找到的元素的迭代器  如果没有找到返回end

程序举例(排序):

学生类
对学生进行排序
按成绩降序
如果成绩相等 则按照年龄升序
如果年龄相等 按学号升序

#include 
#include 
#include 
using namespace std;
class A{
public:
	A(){}
	A(int x){}
};
class Stu{
private:
	int no;
	string name;
	int age;
	int score;
public:
	int getNo()const{
		return no;	
	}
	string getName()const{
		return name;	
	}
	int getAge()const{
		return age;	
	}
	int getScore()const{
		return score;	
	}
	bool operator==(const Stu& s){
		return no == s.no && name == s.name;	
	}
	Stu(int no=0,string name="",int age=0,int score=0):no(no),name(name),
		age(age),score(score){}
	friend ostream& operator<<(ostream& os,const Stu& s){
		return os< s.no;	
		return score < s.score;
	}		
};

template
void print(IT beg,IT end){
	for(IT it = beg; it != end; ++it){
		cout << *it <<  endl;	
	}	
	cout << "===================" << endl;
}

class Comp{
public:	
	int operator()(const Stu& s1,const Stu& s2){
		return s1.getName() < s2.getName();
	}
};

class CompByScore{
public:
	int operator()(const Stu& s1,const Stu& s2){
		return s1.getAge() > s2.getAge();	
	}
};

class CompStu{
public:
	int operator()(const Stu& s1,const Stu& s2){
		if(s1.getScore() == s2.getScore()){
			if(s1.getAge() == s2.getAge()){
				return s1.getNo() < s2.getNo();	
			}
			return s1.getAge() < s2.getAge();
		}
		return s1.getScore() > s2.getScore();
	}
};

int main(){
	vector v;
	v.push_back(Stu(110,"zhangfei",30,88));
	v.push_back(Stu(120,"guangyu",29,90));
	v.push_back(Stu(130,"machao",33,86));
	v.push_back(Stu(140,"huangzhong",44,98));
	v.push_back(Stu(150,"zhao",28,94));
	v.push_back(Stu(160,"zhao",30,94));
	v.push_back(Stu(170,"zhao",30,94));
	v.push_back(Stu(180,"zhao",28,94));
	//没有第三个参数 排序方式由类实现的 <  来决定
	sort(v.begin(),v.end());
	print(v.begin(),v.end());
	//第三个参数决定排序的方式  第三个参数是一个 函数对象(重载了()运算符类的对象)
	sort(v.begin(),v.end(),Comp());
	print(v.begin(),v.end());
	sort(v.begin(),v.end(),CompByScore());
	print(v.begin(),v.end());
	sort(v.begin(),v.end(),CompStu());
	print(v.begin(),v.end());
	find(v.begin(),v.end(),Stu(150,"zhao",28,94));	
	vector va;
	va.resize(10);//调用无参构造
	return 0;	
}

程序举例(查找):

#include 
#include 
#include 
using namespace std;

template
IT search(IT beg,IT end,T data){
	for(IT it = beg;it != end; ++it){
		if(*it == data){
			return it;	
		}	
	}
	return end;
}

int main(){
	vector v;
	v.push_back(5);
	v.push_back(7);
	v.push_back(4);
	v.push_back(8);
	v.push_back(2);
	v.push_back(4);
	vector::iterator it = find(v.begin(),v.end(),4);
	it = find(++it,v.end(),4);
	//vector::iterator it = search(v.begin(),v.end(),4);
	if(it != v.end()){
		cout << "找到了" << *it << endl;
	}else{
		cout << "NOT FOUND" << endl;
	}
	//it = find(v.begin(),v.end(),9);
	it = search(v.begin(),v.end(),9);
	if(it != v.end()){
		cout << "找到了" << *it << endl;
	}else{
		cout << "NOT FOUND" << endl;
	}
	return 0;	
}

你可能感兴趣的:(STL)