STL顺序容器之vector类型
2012-03-16 23:15
417 查看
顺序容器:
将单一类型元素聚集起来成为容器,然后根据位置来存储和访问这些元素,这就是顺序容器。
顺序容器的元素排列与元素值无关,而是由元素添加到容器里的次序决定。
标准库中定义了三种顺序容器类型:vector、list和deque(double-ended queue,双端队列),它们的差别在于访问元素的方式,以及添加或删除元素相关操作的运行代价。
容器只定义了少量操作,大多数额外操作都是由算法库提供。
vector容器:
vector是顺序容器,是STL中最为常用的容器。它的容器以连续的方式存放。熟练掌握vector的使用是进入STL库学习的第一道门槛。
下面通过讲例子的方式慢慢深入vector容器的学习。
知识点预览:
vector<int> v;//定义一个空容器
vector<int> v1(v);//将v通过构造函数拷贝给v1
v.empty();//容器是否为空
vector<int>::iterator it = v.begin();//容器的首元素地址 [begin,end)
v.end();//容器的最后一个元素的下一个位置
v.rbegin();//逆序迭代器,指向容器的最后一个元素
v.rend();//第一个元素前面的位置
v.size();//容器v当前元素的个数
v.resize(n); //调整容器的长度大小,使其能容纳n个元素
v.resize(n,t);//调整大小的同时将新添加的元素的值都设为t
v.max_size();//返回容器可容纳的最多元素个数,返回类型为v::size_type
v.capacity(); //容器v的容量,会自动增长。通常大于size(),加倍分配存储空间。
v.reserve(n);//预留窗外的存储空间。
v.push_back(10);//将值10放入容器v 中
v.insert(p,t);//在迭代器p所指元素的前面插入值为t 的元素
v.insert(p,n,t);//在迭代器所指位置的前面插入n个值为t的元素
v.insert(p,b,e);//在迭代器p指向的元素前面插入迭代器b和e标记范围内的元素
v.at(1) = 20;// 相当于v[1] = 20;
v = v1;//删除v的所有元素,将v1的元素复制给v
v.assign(n,t);//将容器重新设置为存储n个值为 t 的元素
v.assign(b,e);//重新设置v的元素:将迭代器b,e范围内的所有元素复制到v中,b,e必须不是指向c中元素的迭代器
v.front() / v.back() //返回头元素,尾元素的引用
v.swap(v2);//交换两个容器,包括元素值,迭代器及大小等所有数据。比复制的操作快。
v.erase(p);//删除迭代器所指向的元素,它返回一个迭代器,指向被删除元素后面的位置。如果p指向元素的最后一个元素,则返回的迭代器指向容器的超出末端的下一位置。
v.erase(b,e);//删除迭代器b,e范围内的所有元素
v.clear();//删除容器中的所有元素
v.pop_back();//删除容器的最后一个元素
copy(v.begin(),v.end(),ostream_iterator<int>(cout," "));//输出v中一块连续区间的元素的值
fill(b,e,t);//在迭代器b,e范围内填充所有元素的值为t
template<typename T>
class Print{
public:
void operator () (T& t){
cout << t << " ";
}
}
Print<int> print;
for_each(v.begin(),v.end(),print); //自定义输出方式
注:我用的编译环境是C Free + STLport
第一个例子:
使用下标方式和push_back()输入参数至v1中,vector<int> v2310,0),v3中共有10个元素,所有元素赋予初值0。
vector<string> v4(str+0, str+3); 将字符数组str[] 中的内容拷贝至v4中。vector<string>::iterator sIt = v4.begin(); 定义一个迭代器,遍历v4中的所有元素的值。
运行结果:
v1:
3 4 5
v2:
0
v3:
0 0 0 0 0 0 0 0 0 0
v4:
Alex Ajioy Zerian
v5:
Alex Ajioy Zerian
第二个例子:
v.assign(3,100);是将当前v的所有元素清空,用3个值为100的元素替代。
v1.at(1) = 200;相当于v1[1] = 200;,也相当于v1.insert(v1.begin() + 1,200);
copy(v.begin(),v.end(),ostream_iterator<int>(cout," "));是将vector容器中指定的一块连续的区域的元素的值以指定的方式输出,需要包含头文件#include <iterator>
运行结果:
1 2 3 4 5
100 100 100
100 200 300
第三个例子:
class Member的作用在于配合push_back。
v.push_back(M("Robert",60000)); 是把一个M类型(也即Member<string,double>类型)的临时对象压进容器v中,通过迭代器It访问M对象的成员函数print(),输出数据成员name和sal,如此情形下是不可以用v[0],v[1]直接访问v的元素。这种方式很巧妙,通过自定义一个包含多种数据类型的类来保存复杂的数据,既简化了输入输出等操作,又使得结构更加清晰。
M("Robert",60000);相当于
M tmp("Robert",60000);
v.push_back(tmp);
M("Robert",60000);可以把它简单对待成诸如int,string的数据类型,只是它比int,string更复杂一点。
v.back().print()是将容器v中的最后一个元素的值打印出来。
同理可知v.front().print()是打印第一个元素的值。
运行结果:
Enter vector:
name:Robert salary:60000
name:Linda salary:75000
return from back()
name:Linda salary:75000
return from front()
name:Robert salary:60000
第四个例子:
fill(v.begin(),v.end(),5);填充迭代器范围内所有元素的值为5
v.clear();删除所有元素
运行结果:
vector v:5 5 5 5 5 5 5 5 5 5
size of v = 10
v.clear
vector v:
size of v = 0
vector v is empty
100
now v is not empty
第五个例子:
v.resize(7,20);将容器的长度大小在原有基础上调整为7,并且将新添加的元素的值设为20
fill(vc.begin(),vc.end(),'*');在迭代器范围内填充元素的值为*
vc.pop_back();删除最后一个元素
运行结果:
0 2 4 6 8
0 2 4 6 8 20 20
size of vc = 5
* * * * *
* * * * *
size of vc = * * * * *
size of vc = * * * *
size of vc = * * *
size of vc = * *
size of vc = *
第六个例子:
v起初分配的存储长度为5,此时size()和capacity()都为5。随着v.push_back(3); v.push_back(9);这两条语句的增加,容器的长度已经不能满足。不得不分配空间时,它以成倍的分式来开辟空间。即capacity()从5变为10。v.reserve(100);为容器预留100个长度的存储空间。
运行结果:
size of v = 5
capacity of v = 5
value of each elements:1 1 1 1 1
size of v = 7
capacity v = 10
value of each element is :5 8 1 1 1 3 9
size of v1_int:7
capacity of v1_int:100
size of v = 12
第七个例子:
交换两个容器的所有元素
运行结果:
62 13 35 27 73 24 82 74 54 36
size of v1 = 10
35 27 73 24
size of v2 = 4
after swapping...
vector v1:
35 27 73 24
size of v1:4
vector v2:
62 13 35 27 73 24 82 74 54 36
size of vector v2:10
将单一类型元素聚集起来成为容器,然后根据位置来存储和访问这些元素,这就是顺序容器。
顺序容器的元素排列与元素值无关,而是由元素添加到容器里的次序决定。
标准库中定义了三种顺序容器类型:vector、list和deque(double-ended queue,双端队列),它们的差别在于访问元素的方式,以及添加或删除元素相关操作的运行代价。
容器只定义了少量操作,大多数额外操作都是由算法库提供。
vector容器:
vector是顺序容器,是STL中最为常用的容器。它的容器以连续的方式存放。熟练掌握vector的使用是进入STL库学习的第一道门槛。
下面通过讲例子的方式慢慢深入vector容器的学习。
知识点预览:
vector<int> v;//定义一个空容器
vector<int> v1(v);//将v通过构造函数拷贝给v1
v.empty();//容器是否为空
vector<int>::iterator it = v.begin();//容器的首元素地址 [begin,end)
v.end();//容器的最后一个元素的下一个位置
v.rbegin();//逆序迭代器,指向容器的最后一个元素
v.rend();//第一个元素前面的位置
v.size();//容器v当前元素的个数
v.resize(n); //调整容器的长度大小,使其能容纳n个元素
v.resize(n,t);//调整大小的同时将新添加的元素的值都设为t
v.max_size();//返回容器可容纳的最多元素个数,返回类型为v::size_type
v.capacity(); //容器v的容量,会自动增长。通常大于size(),加倍分配存储空间。
v.reserve(n);//预留窗外的存储空间。
v.push_back(10);//将值10放入容器v 中
v.insert(p,t);//在迭代器p所指元素的前面插入值为t 的元素
v.insert(p,n,t);//在迭代器所指位置的前面插入n个值为t的元素
v.insert(p,b,e);//在迭代器p指向的元素前面插入迭代器b和e标记范围内的元素
v.at(1) = 20;// 相当于v[1] = 20;
v = v1;//删除v的所有元素,将v1的元素复制给v
v.assign(n,t);//将容器重新设置为存储n个值为 t 的元素
v.assign(b,e);//重新设置v的元素:将迭代器b,e范围内的所有元素复制到v中,b,e必须不是指向c中元素的迭代器
v.front() / v.back() //返回头元素,尾元素的引用
v.swap(v2);//交换两个容器,包括元素值,迭代器及大小等所有数据。比复制的操作快。
v.erase(p);//删除迭代器所指向的元素,它返回一个迭代器,指向被删除元素后面的位置。如果p指向元素的最后一个元素,则返回的迭代器指向容器的超出末端的下一位置。
v.erase(b,e);//删除迭代器b,e范围内的所有元素
v.clear();//删除容器中的所有元素
v.pop_back();//删除容器的最后一个元素
copy(v.begin(),v.end(),ostream_iterator<int>(cout," "));//输出v中一块连续区间的元素的值
fill(b,e,t);//在迭代器b,e范围内填充所有元素的值为t
template<typename T>
class Print{
public:
void operator () (T& t){
cout << t << " ";
}
}
Print<int> print;
for_each(v.begin(),v.end(),print); //自定义输出方式
注:我用的编译环境是C Free + STLport
第一个例子:
使用下标方式和push_back()输入参数至v1中,vector<int> v2310,0),v3中共有10个元素,所有元素赋予初值0。
vector<string> v4(str+0, str+3); 将字符数组str[] 中的内容拷贝至v4中。vector<string>::iterator sIt = v4.begin(); 定义一个迭代器,遍历v4中的所有元素的值。
#include <iostream> #include <vector> #include <algorithm> using namespace std; int main(){ //empty vector object vector<int> v1; v1.push_back(3); v1[1] = 4; v1[2] = 5; cout << "v1:" << endl; for(int i = 0; i < 3; ++i) cout << v1[i] << " "; cout << endl; //creates vector with ten object elements vector<int> v2(10); cout << "v2:" << endl << v2[0] << endl; //creates vector with ten object elements //and assigned value 0 for each vector<int> v3(10,0); cout << "v3:" << endl; for(int i = 0; i < 10; ++i) cout << v3[i] << " "; cout << endl; string str[] = {"Alex","Ajioy","Zerian"}; // copy str,str+1,str+2 to v4 vector<string> v4(str+0, str+3); vector<string>::iterator sIt = v4.begin(); cout << "v4:" << endl; while(sIt != v4.end()) cout << *sIt++ << " "; cout << endl; vector<string> v5(v4); cout << "v5:" << endl; for(int i = 0; i < 3; ++i) cout << v5[i] << " "; cout << endl; return 0; }
运行结果:
v1:
3 4 5
v2:
0
v3:
0 0 0 0 0 0 0 0 0 0
v4:
Alex Ajioy Zerian
v5:
Alex Ajioy Zerian
第二个例子:
v.assign(3,100);是将当前v的所有元素清空,用3个值为100的元素替代。
v1.at(1) = 200;相当于v1[1] = 200;,也相当于v1.insert(v1.begin() + 1,200);
copy(v.begin(),v.end(),ostream_iterator<int>(cout," "));是将vector容器中指定的一块连续的区域的元素的值以指定的方式输出,需要包含头文件#include <iterator>
#include <iostream> #include <vector> #include <iterator> using namespace std; int main(){ int arr[] = {1,2,3,4,5}; vector<int> v; //assign to the "v",the contains of "arr" v.assign(arr,arr+5); copy(v.begin(),v.end(), ostream_iterator<int>(cout," ")); cout << endl; //replace v for 3 copies of 100 v.assign(3,100); copy(v.begin(),v.end(), ostream_iterator<int>(cout," ")); cout << endl; vector<int> v1(3,0); v1[0] = 100; v1.at(1) = 200; v1.insert(v1.begin() + 2,300); for(int i = 0; i < 3; ++i) cout << v1.at(i) << " "; cout << endl; }
运行结果:
1 2 3 4 5
100 100 100
100 200 300
第三个例子:
class Member的作用在于配合push_back。
v.push_back(M("Robert",60000)); 是把一个M类型(也即Member<string,double>类型)的临时对象压进容器v中,通过迭代器It访问M对象的成员函数print(),输出数据成员name和sal,如此情形下是不可以用v[0],v[1]直接访问v的元素。这种方式很巧妙,通过自定义一个包含多种数据类型的类来保存复杂的数据,既简化了输入输出等操作,又使得结构更加清晰。
M("Robert",60000);相当于
M tmp("Robert",60000);
v.push_back(tmp);
M("Robert",60000);可以把它简单对待成诸如int,string的数据类型,只是它比int,string更复杂一点。
v.back().print()是将容器v中的最后一个元素的值打印出来。
同理可知v.front().print()是打印第一个元素的值。
#include <iostream> #include <vector> #include <iterator> #include <string> using namespace std; template <typename T,typename D> class Member{ public: Member(T t,D d):name(t),sal(d){} void print(); private: T name; D sal; }; template<typename T,typename D> void Member<T,D>::print() { cout << "name:" << name << " salary:" << sal << endl; } typedef Member<string,double> M; int main(){ vector<M> v; v.push_back(M("Robert",60000)); v.push_back(M("Linda",75000)); vector<M>::iterator It = v.begin(); cout << "Enter vector:" << endl; while(It != v.end()) (It++)->print(); cout << endl; cout << "return from back()" << endl; v.back().print(); cout << "return from front()" << endl; v.front().print(); }
运行结果:
Enter vector:
name:Robert salary:60000
name:Linda salary:75000
return from back()
name:Linda salary:75000
return from front()
name:Robert salary:60000
第四个例子:
fill(v.begin(),v.end(),5);填充迭代器范围内所有元素的值为5
v.clear();删除所有元素
#include <iostream> #include <vector> #include <algorithm> using namespace std; template <class T> class Print{ public: void operator() (T & t) { cout << t << " " ; } }; int main() { vector<int> v(10); Print<int> print; //set all elements as 5 fill(v.begin(),v.end(),5); cout << "vector v:"; for_each(v.begin(),v.end(),print); cout << endl; cout << "size of v = " << v.size() << endl; cout << "v.clear" << endl; //clear all elements of container v.clear(); cout << "vector v:"; for_each(v.begin(),v.end(),print); cout << endl; cout << "size of v = " << v.size() << endl; cout << "vector v is "; v.empty()? cout << "" : cout << "not "; cout << "empty" << endl; v.push_back(100); cout << v[0] << endl; cout << "now v is "; v.empty() ? cout << "" : cout << "not "; cout << "empty" << endl; }
运行结果:
vector v:5 5 5 5 5 5 5 5 5 5
size of v = 10
v.clear
vector v:
size of v = 0
vector v is empty
100
now v is not empty
第五个例子:
v.resize(7,20);将容器的长度大小在原有基础上调整为7,并且将新添加的元素的值设为20
fill(vc.begin(),vc.end(),'*');在迭代器范围内填充元素的值为*
vc.pop_back();删除最后一个元素
#include <iostream> #include <vector> #include <iterator> #include <algorithm> using namespace std; int main(){ /* resize */ vector<int> v(5); for(int i = 0; i < 5; ++i) v[i] = i * 2; //copy() function need include "iterator" copy(v.begin(), v.end(), ostream_iterator<int>(cout," ")); cout << endl; //reset the size and fill with 20 v.resize(7,20); copy(v.begin(),v.end(), ostream_iterator<int>(cout," ")); cout << endl << endl; /* size */ vector<char> vc(5); cout << "size of vc = " << vc.size() << endl; fill(vc.begin(),vc.end(),'*'); copy(vc.begin(),vc.end(),ostream_iterator<char>(cout," ")); cout << endl; for(int i = 0; i < v.size(); ++i) cout << vc[i] << " "; cout << endl; for(int i = 0; i < 5; ++i){ cout << "size of vc = " ; copy(vc.begin(),vc.end(),ostream_iterator<char>(cout," ")); cout << endl; //pop up 1 element vc.pop_back(); } }
运行结果:
0 2 4 6 8
0 2 4 6 8 20 20
size of vc = 5
* * * * *
* * * * *
size of vc = * * * * *
size of vc = * * * *
size of vc = * * *
size of vc = * *
size of vc = *
第六个例子:
v起初分配的存储长度为5,此时size()和capacity()都为5。随着v.push_back(3); v.push_back(9);这两条语句的增加,容器的长度已经不能满足。不得不分配空间时,它以成倍的分式来开辟空间。即capacity()从5变为10。v.reserve(100);为容器预留100个长度的存储空间。
#include <iostream> #include <vector> using namespace std; template<typename T> class Print{ public: void operator() (T& t){ cout << t << " "; } }; int main(){ vector<int> v(5,1); cout << "size of v = " << v.size() << endl; cout << "capacity of v = " << v.capacity() << endl; cout << "value of each elements:" ; for(int i = 0; i < v.size(); ++i) cout << v[i] << " "; cout << endl; //modify the elements v[0] = 5; v[1] = 8; v.push_back(3); v.push_back(9); cout << endl; cout << "size of v = " << v.size() << endl; //capacity is typically larger than size cout << "capacity v = " << v.capacity() << endl; Print<int> print; cout << "value of each element is :"; for_each(v.begin(),v.end(),print); cout << endl; v.reserve(100); // increase capacity to 100 cout << "size of v1_int:" << v.size() << endl; cout << "capacity of v1_int:" << v.capacity() << endl; // i don't know why the size of vector v is 12 int size = sizeof(v); cout << "size of v = " << size << endl; }
运行结果:
size of v = 5
capacity of v = 5
value of each elements:1 1 1 1 1
size of v = 7
capacity v = 10
value of each element is :5 8 1 1 1 3 9
size of v1_int:7
capacity of v1_int:100
size of v = 12
第七个例子:
交换两个容器的所有元素
#include <iostream> #include <vector> #include <algorithm> #include <ctime> #include <iterator> using namespace std; int main(){ srand(unsigned(time(0))); int arr[10]; const int max = 100; const int min = 50; //generate 10 random numbers for(int i = 0; i < 10; ++i) arr[i] = max * rand() / (RAND_MAX + min) + 1; vector<int> v1(arr,arr+10); vector<int> v2(arr+2,arr+6); copy(v1.begin(),v1.end(),ostream_iterator<int>(cout," ")); cout << endl << "size of v1 = " << v1.size() << endl; copy(v2.begin(),v2.end(),ostream_iterator<int>(cout," ")); cout << endl << "size of v2 = " << v2.size() << endl; v1.swap(v2); cout << "after swapping..." << endl << "vector v1:" << endl; copy(v1.begin(),v1.end(),ostream_iterator<int>(cout," ")); cout << endl << "size of v1:" << v1.size() << endl; cout << "vector v2:" << endl; copy(v2.begin(),v2.end(),ostream_iterator<int>(cout," ")); cout << endl << "size of vector v2:" << v2.size() << endl; }
运行结果:
62 13 35 27 73 24 82 74 54 36
size of v1 = 10
35 27 73 24
size of v2 = 4
after swapping...
vector v1:
35 27 73 24
size of v1:4
vector v2:
62 13 35 27 73 24 82 74 54 36
size of vector v2:10
相关文章推荐
- STL顺序容器之vector类型
- STL顺序容器之vector类型
- STL 笔记(一) 顺序容器 vector、list、deque
- STL学习:顺序容器-vector
- STL-顺序容器-向量vector
- STL—vector容器类型
- 【STL】容器 > 顺序容器 > vector
- STL1—顺序容器vector list deque的基本知识
- C++的STL容器之顺序性容器vector、list、deque
- 熟悉STL顺序容器的使用之vector
- STL中vector容器中元素为自定义类型时的效率分析
- stl 顺序容器vector(priority_queue),顺序容器List,顺序容器deque(queue, stack)详解
- STL中vector容器中元素为自定义类型指针时的内存泄漏问题
- 从零开始学C++之STL(三):迭代器类vector::iterator 和 vector::reverse_iterator 的实现、迭代器类型、常用的容器成员
- STL顺序容器-vector
- STL顺序容器vector,list和deque
- STL顺序容器vector与list
- STL 顺序容器之Vector
- C++之STL(三):迭代器类vector::iterator 和 vector::reverse_iterator 的实现、迭代器类型、常用的容器成员
- STL 顺序容器之Vector