把三个常用的序列式放在一起对比一下是有必要的:
vector : vector和built-in数组类似,拥有一段连续的内存空间,能非常好的支持随即存取,即[]操作符,但由于它的内存空间是连续的,所以在中间进行插入和删除会造成内存块的拷贝,另外,当插入较多的元素后,预留内存空间可能不够,需要重新申请一块足够大的内存并把原来的数据拷贝到新的内存空间。这些影响了vector的效率,但是实际上用的最多的还是vector容器,建议大多数时候使用vector效率一般是不错的。
list: list就是数据结构中的双向链表(根据sgi stl源代码),因此它的内存空间是不连续的,通过指针来进行数据的访问,这个特点使得它的随即存取变的非常没有效率,因此它没有提供[]操作符的重载。但由于链表的特点,它可以以很好的效率支持任意地方的删除和插入。
deque: deque是一个double-ended queue,它的具体实现不太清楚,但知道它具有以下两个特点:它支持[]操作符,也就是支持随即存取,并且和vector的效率相差无几,它支持在两端的操作:push_back,push_front,pop_back,pop_front等,并且在两端操作上与list的效率也差不多。
因此在实际使用时,如何选择这三个容器中哪一个,应根据你的需要而定,具体可以遵循下面的原则:
1. 如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
2. 如果你需要大量的插入和删除,而不关心随即存取,则应使用list
3. 如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。
一、C++ vector类为内置数组提供了一种替代表示,与string类一样 vector 类是随标准 C++引入的标准库的一部分,使用时需包含头文件:
#include <vector>
二、C++ vector类有两种使用方式:
第一种:STL方式
vector< string > text;
1. 我们向 vector 中插入元素,而不再是索引元素,以及向元素赋值,例如 push_back()操作,就是在 vector 的后面插入一个元素下面的 while 循环从标准输入读入一个字符串序列并每次将一个字符串插入到 vector 中
string word;
while ( cin >> word ) {
text.push_back( word );
// ...
}
虽然我们仍可以用下标操作符来迭代访问元素
cout << "words read are: \n";
for ( int ix = 0; ix < text.size(); ++ix )
cout << text[ ix ] << ' ';
cout << endl;
但是 更典型的做法是使用vector 操作集中的begin()和 end()所返回的迭代器 iterator
对 :
cout << "words read are: \n";
for ( vector<string>::iterator it = text.begin();
it != text.end(); ++it )
cout << *it<< ' ';
cout << endl
iterator 是标准库中的类,它具有指针的功能
*it 是对迭代器解引用,并访问其指向的实际对象
++it向前移动迭代器 it 使其指向下一个元素
2. 注意 不要混用这两种习惯用法, 例如,下面的定义
vector< int > ivec;
定义了一个空vector 再写这样的语句
ivec[ 0 ] = 1024;
就是错误的 ,因为 ivec 还没有第一个元素,我们只能索引 vector 中已经存在的元素;
size()操作返回 vector 包含的元素的个数。
3. 类似地 当我们用一个给定的大小定义一个vector 时,例如 :
vector<int> ia( 10 );
任何一个插入操作都将增加vector 的大小,而不是覆盖掉某个现有的元素,这看起来好像是很显然的,但是下面的错误在初学者中并不少见:
const int size = 7;
int ia[ size ] = { 0, 1, 1, 2, 3, 5, 8 };
vector< int > ivec( size );
for ( int ix = 0; ix < size; ++ix )
ivec.push_back( ia[ ix ]);
程序结束时ivec 包含 14 个元素, ia 的元素从第八个元素开始插入。
第二种:类数组使用
1. 定义一个已知长度的 vector :
vector< int > ivec(10); //类似数组定义int ia[10];
可以通过ivec[索引号] 来访问元素
使用 if ( ivec.empty() ) 判断是否是空,ivec.size()判断元素个数。
2. vector的元素被初始化为与其类型相关的缺省值:算术和指针类型的缺省值是0,对于class 类型,缺省值可通过调用这类的缺省构造函数获得,我们还可以为每个元素提供一个显式的初始值来完成初始化,例如
vector< int > ivec( 10, -1 );
定义了 ivec 它包含10个int型的元素每个元素都被初始化为-1
对于内置数组我们可以显式地把数组的元素初始化为一组常量值,例如:
int ia[ 6 ] = { -2, -1, 0, 1, 2, 1024 };
我们不能用同样的方法显式地初始化 vector ,但是可以将 vector 初始化为一个已有数组的全部或一部分,只需指定希望被用来初始化 vector 的数组的开始地址以及数组最末元的下一位置来实现,例如:
// 把 ia 的 6 个元素拷贝到 ivec 中
vector< int > ivec( ia, ia+6 );
被传递给ivec 的两个指针标记了用来初始化对象的值的范围,第二个指针总是指向要拷贝的末元素的下一位置,标记出来的元素范围也可以是数组的一个子集,例如 :
// 拷贝 3 个元素 ia[2],ia[3], ia[4]
vector< int > ivec( &ia[2], &ia[5] );
3. 与内置数组不同 vector 可以被另一个 vector 初始化或被赋给另一个 vector 例如
vector< string > svec;
void init_and_assign()
{
// 用另一个 vector 初始化一个 vector
vector< string > user_names( svec );
// ...
// 把一个 vector 拷贝给另一个 vector
svec = user_names;
}
三、vector使用总结:
vector 是向量类型,它可以容纳许多类型的数据,如若干个整数,所以称其为容器。vector 是C++ STL的一个重要成员,使用它时需要包含头文件:
#include<vector>;
1、vector 的初始化:可以有五种方式,举例说明如下:
(1) vector<int> a(10); //定义了10个整型元素的向量(尖括号中为元素类型名,它可以是任何合法的数据类型),但没有给出初值,其值是不确定的。
(2)vector<int> a(10,1); //定义了10个整型元素的向量,且给出每个元素的初值为1
(3)vector<int> a(b); //用b向量来创建a向量,整体复制性赋值
(4)vector<int> a(b.begin(),b.begin+3); //定义了a值为b中第0个到第2个(共3个)元素
(5)int b[7]={1,2,3,4,5,9,8};
vector<int> a(b,b+7); //从数组中获得初值
2、vector对象的几个重要操作,举例说明如下:
(1)a.assign(b.begin(), b.begin()+3); //b为向量,将b的0~2个元素构成的向量赋给a
(2)a.assign(4,2); //是a只含4个元素,且每个元素为2
(3)a.back(); //返回a的最后一个元素
(4)a.front(); //返回a的第一个元素
(5)a[i]; //返回a的第i个元素,当且仅当a[i]存在2013-12-07
(6)a.clear(); //清空a中的元素
(7)a.empty(); //判断a是否为空,空则返回ture,不空则返回false
(8)a.pop_back(); //删除a向量的最后一个元素
(9)a.erase(a.begin()+1,a.begin()+3); //删除a中第1个(从第0个算起)到第2个元素,也就是说删除的元素从a.begin()+1算起(包括它)一直到a.begin()+ 3(不包括它)
(10)a.push_back(5); //在a的最后一个向量后插入一个元素,其值为5
(11)a.insert(a.begin()+1,5); //在a的第1个元素(从第0个算起)的位置插入数值5,如a为1,2,3,4,插入元素后为1,5,2,3,4
(12)a.insert(a.begin()+1,3,5); //在a的第1个元素(从第0个算起)的位置插入3个数,其值都为5
(13)a.insert(a.begin()+1,b+3,b+6); //b为数组,在a的第1个元素(从第0个算起)的位置插入b的第3个元素到第5个元素(不包括b+6),如b为1,2,3,4,5,9,8 ,插入元素后为1,4,5,9,2,3,4,5,9,8
(14)a.size(); //返回a中元素的个数;
(15)a.capacity(); //返回a在内存中总共可以容纳的元素个数
(16)a.resize(10); //将a的现有元素个数调至10个,多则删,少则补,其值随机
(17)a.resize(10,2); //将a的现有元素个数调至10个,多则删,少则补,其值为2
(18)a.reserve(100); //将a的容量(capacity)扩充至100,也就是说现在测试a.capacity();的时候返回值是100.这种操作只有在需要给a添加大量数据的时候才 显得有意义,因为这将避免内存多次容量扩充操作(当a的容量不足时电脑会自动扩容,当然这必然降低性能)
(19)a.swap(b); //b为向量,将a中的元素和b中的元素进行整体性交换
(20)a==b; //b为向量,向量的比较操作还有!=,>=,<=,>,<
3、顺序访问vector的几种方式,举例说明如下:
(1)向向量a中添加元素
1、
1 vector<int> a;
2 for(int i=0;i<10;i++) { a.push_back(i); }
2、也可以从数组中选择元素向向量中添加
int a[6]={1,2,3,4,5,6};
vector<int> b;
for(int i=1;i<=4;i++) { b.push_back(a[i]); }
3、也可以从现有向量中选择元素向向量中添加
int a[6]={1,2,3,4,5,6};
vector<int> b;
vector<int> c(a,a+4);
for(vector<int>::iterator it=c.begin();it<c.end();it++) { b.push_back(*it); }
4、也可以从文件中读取元素向向量中添加
ifstream in("data.txt");
vector<int> a;
for(int i; in>>i)
a.push_back(i);
5、【误区】
vector<int> a;
for(int i=0;i<10;i++) { a[i]=i; }
//这种做法以及类似的做法都是错误的。刚开始我也犯过这种错误,后来发现,下标只能用于获取已存在的元素,而现在的a[i]还是空的对象
(2)从向量中读取元素
1、通过下标方式读取
int a[6]={1,2,3,4,5,6};
vector<int> b(a,a+4);
for(int i=0;i<=b.size()-1;i++)
cout<<b[i]<<" ";
2、通过遍历器方式读取
int a[6]={1,2,3,4,5,6};
vector<int> b(a,a+4);
for(vector<int>::iterator it=b.begin();it!=b.end();it++)
cout<<*it<<" ";
四、几种重要的算法,使用时需要包含头文件:
#include<algorithm>
(1)sort(a.begin(),a.end()); //对a中的从a.begin()(包括它)到a.end()(不包括它)的元素进行从小到大排列
(2)reverse(a.begin(),a.end()); //对a中的从a.begin()(包括它)到a.end()(不包括它)的元素倒置,但不排列,如a中元素为1,3,2,4,倒置后为4,2,3,1
(3)copy(a.begin(),a.end(),b.begin()+1); //把a中的从a.begin()(包括它)到a.end()(不包括它)的元素复制到b中,从b.begin()+1的位置(包括它)开始复制,覆盖掉原有元素
(4)find(a.begin(),a.end(),10); //在a中的从a.begin()(包括它)到a.end()(不包括它)的元素中查找10,若存在返回其在向量中的位置
五、其它使用举例:
(1)把一个vector中元素追加到另外一个容器vector,示例程序如下:
#include <vector>
#include <iostream>
template <typename type> void printvector(std::vector<type> const &v, std::ostream &os = std::cout)
{
for (typename std::vector<type>::size_type sz = 0; sz != v.size(); ++sz)
os << v[sz] << " ";
os << std::endl;
}
int main()
{
int a[5] = {1, 2, 3, 4, 5};
std::vector<int> v1(a, a + 3), v2(a + 3, a + 5);
printvector(v1); // 结果是1 2 3
printvector(v2); // 结果是4 5
v1.insert(v1.end(), v2.begin(), v2.end()); // 把v2加到v1末尾
printvector(v1); // 结果是1 2 3 4 5
return 0;
}
(2)类和结构体存vector入实例:由于vector只允许一个占位,所以才将struct塞进vector,以弥补vector的不足。
1. #include "stdafx.h"
2. #include <vector>
3. #include <string>
4. using namespace std;
5. class AClass
6. {
7. public:
8. int num;
9. string name;
10. };
11. struct AStruct
12. {
13. int num;
14. string name;
15. };
16. void TestStruct()
17. {
18. //类的使用
19. AClass Ac;
20. vector<AClass> vc;
21. Ac.num=10;
22. Ac.name="name";
23. vc.push_back(Ac);
24. AClass d;
25. for (vector<AClass>::iterator it=vc.begin();it<vc.end();++it)
26. {
27. d=*it;
28. cout<<d.num<<endl;
29. }
30. //结构体的使用
31. AStruct As;
32. vector<AStruct> vs;
33. As.num=10;
34. As.name="name";
35. vs.push_back(As);
36. AStruct ds;
37. for (vector<AStruct>::iterator it=vs.begin();it<vs.end();++it)
38. {
39. ds=*it;
40. cout<<ds.num<<endl;
41. }
42. }
43. void TestPoint()
44. {
45. //类的使用
46. AClass *Ac=new AClass;
47. vector<AClass *> vc;
48. Ac->num=10;
49. Ac->name="name";
50. vc.push_back(Ac);
51. AClass *d;
52. for (vector<AClass*>::iterator it=vc.begin();it<vc.end();++it)
53. {
54. d=*it;
55. cout<<d->num<<endl;
56. }
57. }
58. int _tmain(int argc, _TCHAR* argv[])
59. {
60. TestStruct();
61. TestPoint();
62. int n;
63. cin>>n;
64. return 0;
65. }
(3)C++中将两个vector中的值整合到另一个vector中,vecB和vecA中有相同的struct个数,现在想将每个vecA中的每个a的值传给vecC中c1,每个vecB中的每个b的值传给vecC中c2,也就是将两个容器中的内容整合到新的容器C中
1. struct A
2. {
3. int a;
4. };
5. vector<A> vecA;
6. struct B
7. {
8. int b;
9. };
10. vector<B> vecB;
11. struct C
12. {
13. int c1;
14. int c2;
15. };
16. vector<C> vecC;
容器C和A、B中元素类型不同,迭代器类型就不同,所以不能用容器算法,使用迭代器遍历赋值,合并代码如下:
第一种方法:
1. for(vecA::const_iterator itA = vecA.begin(), VecB::const_iterator itB = vecB.begin();
2. itA != vecA.end() && itB != vecB.end(); itA++, itB++){
3. C c;
4. c.c1 = (*itA).a;
5. c.c2 = (*itB).b;
6. vecC.push_back(c);
7. }
第二种方法:
1. void MergeVector(vector<A> &vectorA,vector<B> &vectorB,vector<C> &vectorC)
2. {
3. vector<A>::iterator pva;
4. vector<B>::iterator pvb;
5. vector<C>::iterator pvc;
6. pva = vectorA.begin();
7. pvb = vectorB.begin();
8. pvc = vectorC.begin();
9. while(pva!=vectorA.end())
10. {
11. *pvc->c1 = *pva->a;
12. *pvc->c2 = *pvb->b;
13. pva++;
14. pvb++;
15. pvc++;
16. }
17. }
(4)建立两个int类型的向量vector,利用merge算法合并,再用sort算法对合并后算法排序
1. #include <iostream>
2. #include <vector>
3. #include <algorithm>
4. using namespace std;
5. vector<int> merge(vector<int> ,vector<int> );
6. int main()
7. {
8. vector<int> v1;
9. v1.push_back(4);
10. v1.push_back(6);
11. v1.push_back(2);
12. vector<int> v2;
13. v2.push_back(3);
14. v2.push_back(1);
15. v2.push_back(5);
16. vector<int> v3=merge(v1,v2);
17. sort(v3.begin(),v3.end());
18. for(vector<int>::iterator it=v3.begin();it!=v3.end();++it){
19. cout<<*it<<endl;
20. }
21. }
22. vector<int> merge(vector<int> v1,vector<int> v2)
23. {
24. v1.insert(v1.end(),v2.begin(),v2.end());
25. return v1;
26. }
增删改查接口封装演示
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct Student
{
int id;
string name;
int score;
};
#define func_log(s, s2) do {cout << "[" << s << "] " << s2 << endl;} while (0);
vector<Student> Students;
void add(Student &obj)
{
func_log(__func__, "");
Students.push_back(obj);
}
void remove(int id)
{
func_log(__func__, "");
vector<Student>::iterator it = Students.begin();
for (it; it != Students.end(); it++)
{
if (id == it->id)
{
cout << "remove: " << id << endl;
Students.erase(it);
break;
}
}
func_log(__func__, "end");
}
void modify(Student &obj)
{
func_log(__func__, "");
vector<Student>::iterator it = Students.begin();
for (it; it != Students.end(); it++)
{
if (obj.id == it->id)
{
cout << "modify: [id]: " << obj.id << endl;
cout << "modify: [name]: " << obj.name << endl;
cout << "modify: [score]: " << obj.score << endl;
*it = obj;
break;
}
}
func_log(__func__, "end");
}
int search(int id, Student &obj)
{
func_log(__func__, "begin");
int result = false;
vector<Student>::iterator it = Students.begin();
for (it; it != Students.end(); it++)
{
if (id == it->id)
{
obj = *it;
cout << "Found: [id]: " << obj.id << endl;
cout << "Found: [name]: " << obj.name << endl;
cout << "Found: [score]: " << obj.score << endl;
result = true;
break;
}
}
func_log(__func__, "end");
return result;
}
void show()
{
cout << "#####################" << endl;
vector<Student>::iterator it = Students.begin();
for (it; it != Students.end(); it++)
{
cout << it->id << " ";
cout << it->name << " " ;
cout << it->score << endl;
}
cout << "#####################" << endl;
}
int main() {
Student st1 = {1, "laoyang", 99};
Student st2 = {2, "laoyanj", 98};
Student st3 = {3, "laoyanh", 97};
Student st4 = {4, "laoyani", 96};
add(st1);
add(st2);
add(st3);
add(st4);
show();
Student stu;
if (search(3, stu))
{
cout << "search OK" << endl;
cout << "\tid: " << stu.id << endl;
cout << "\tname: " << stu.name << endl;
cout << "\tscore: " << stu.score << endl;
}
else
{
cout << "search Failed." << endl;
}
stu.id = 1;
modify(stu);
show();
remove(2);
show();
return 0;
}
/*****************************************
* Copyright (C) 2018 * Ltd. All rights reserved.
*
* File name : vector.cpp
* Author : longbin
* Created date: 2018-08-02 19:18:13
* Description :
*
*******************************************/
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#define print(s) do {cout << "[" << __func__ << "] " << #s << ": " << s << endl;} while (0);
template <class T>
void show(T& val)
{
typename T::iterator it;
cout << "[" << __func__ << "]: ";
for (it = val.begin(); it != val.end(); it++)
{
cout << *it;
if (it != val.end() -1)
{
cout << ", ";
}
}
cout << endl;
}
void vec_construct()
{
// default (1) explicit vector (const allocator_type& alloc = allocator_type());
// fill (2) explicit vector (size_type n, const value_type& val = value_type(),
// const allocator_type& alloc = allocator_type());
// range (3) template <class InputIterator>
// vector (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type());
// copy (4) vector (const vector& x);
// (1) empty container constructor (default constructor) // Constructs an empty container, with no elements.
// (2) fill constructor // Constructs a container with n elements. Each element is a copy of val.
// (3) range constructor // Constructs a container with as many elements as the range [first,last).
// (4) copy constructor // Constructs a container with a copy of each of the elements in x, in the same order.
vector<int> vi; // (1) empty vector of ints;
vector<string> vs; // (1) empty vector of strings;
vector<int> vi2(6, 258); // (2) 6 ints with value 258;
vector<int> vi20(6); // (2) 6 ints with value 258;
vector<string> vs2(3, "c++"); // (2) 3 strings with value of "c++";
vector<int> vi3(vi2.begin()+1, vi2.begin()+3); // (3) iteratoring from vi2;
vector<string> vs3(vs2.begin(), vs2.end()); // (3) iteratoring from vi2;
vector<int> vi4(vi2); // (4) a copy of vi2;
vector<string> vs4(vs2); // (4) a copy of vs2;
show(vi); // show:
show(vs); // show:
show(vi2); // show: 258, 258, 258, 258, 258, 258,
show(vi20); // show: 0, 0, 0, 0, 0, 0
show(vs2); // show: c++, c++, c++,
show(vi3); // show: 258, 258,
show(vs3); // show: c++, c++, c++,
show(vi4); // show: 258, 258, 258, 258, 258, 258,
show(vs4); // show: c++, c++, c++,
}
void vec_OperatorEQ()
{
// Assign content
// Assigns new contents to the container, replacing its current contents, and modifying its size accordingly.
// copy (1) vector& operator= (const vector& x);
// move (2) vector& operator= (vector&& x); //c++11
// initializer list (3) vector& operator= (initializer_list<value_type> il); //c++11
vector<int> vi1(5, 0);
vector<int> vi2(6, 0);
vi2 = vi1;
vi1 = vector<int>();
print(vi1.size());
print(vi2.size());
vector<int> vi5 = {1,2,3,4,5,6}; // c++11 要求类型相容
vector<int> vi51 {1,2,3,4,5,6}; // c++11 =可省略
show(vi5); // show: 1, 2, 3, 4, 5, 6
show(vi51); // show: 1, 2, 3, 4, 5, 6
}
void vec_begin_end()
{
// iterator begin();
// const_iterator begin() const;
// Return iterator to beginning // Returns an iterator pointing to the first element in the vector.
// iterator end();
// const_iterator end() const;
// Return iterator to end // Returns an iterator referring to the past-the-end element in the vector container.
vector<int> vi;
int i = 0;
for (i = 1; i <= 9; i++)
{
vi.push_back(i);
}
vector<int>::iterator it;
cout << "[" << __func__ << "]: ";
for (it = vi.begin(); it != vi.end(); it++)
{
cout << *it;
if (it != vi.end() - 1)
{
cout << ", ";
}
}
cout << endl;
}
void vec_size()
{
// Return size // Returns the number of elements in the vector.
// size_type size() const;
vector<int> vi;
print(vi.size()); //0
int i = 0;
for (i = 1; i <= 9; i++)
{
vi.push_back(i);
}
print(vi.size()); //9
vi.insert(vi.end(), 10, 100);
print(vi.size()); //19
vi.pop_back();
print(vi.size()); //18
}
void vec_capacity()
{
// size_type capacity() const;
// Return size of allocated storage capacity
// Returns the size of the storage space currently allocated for the vector, expressed in terms of elements.
vector<int> vi;
int i = 0;
for (i = 1; i <= 9; i++)
{
vi.push_back(i);
}
print(vi.size()); //9
print(vi.capacity()); //16
print(vi.max_size()); //4611686018427387903
vi.insert(vi.end(), 10, 100);
print(vi.size()); //19
print(vi.capacity()); //19
print(vi.max_size()); //4611686018427387903
}
void vec_empty()
{
// bool empty() const;
// Test whether vector is empty
// Returns whether the vector is empty (i.e. whether its size is 0).
// This function does not modify the container in any way. To clear the content of a vector, see vector::clear.
vector<int> vi;
int i = 0;
int sum = 0;
print(vi.empty()); //1
for (i = 1; i <= 9; i++)
{
vi.push_back(i);
}
print(vi.empty()); //0
while (!vi.empty())
{
sum += vi.back();
vi.pop_back();
}
print(vi.empty()); //1
print(sum); //45
}
void vec_OperatorAT()
{
// reference operator[] (size_type n);
// const_reference operator[] (size_type n) const;
// Access element
// Returns a reference to the element at position n in the vector container.
// A similar member function, vector::at, has the same behavior as this operator function,
// except that vector::at is bound-checked and signals if the requested position is out of
// range by throwing an out_of_range exception.
// Notice that the first element has a position of 0 (not 1).
vector<int> vi(10); //10 zero-initialized elements
vector<int>::size_type size = vi.size();
unsigned int i = 0;
for (i = 0; i < size; i++)
{
vi[i] = i;
}
show(vi);
// reverse vector using operator[]
for (i = 0; i < size/2; i++)
{
vi[i] ^= vi[size-1-i];
vi[size-1-i] ^= vi[i];
vi[i] ^= vi[size-1-i];
}
cout << "[" << __func__ << "]: ";
for (i = 0; i < size; i++)
{
cout << vi[i];
if (i != size - 1)
{
cout << ", ";
}
}
cout << endl;
}
void vec_at()
{
// reference at (size_type n);
// const_reference at (size_type n) const;
// Access element
// Returns a reference to the element at position n in the vector.
// The function automatically checks whether n is within the bounds of valid elements in the vector,
// throwing an out_of_range exception if it is not (i.e., if n is greater than, or equal to, its size).
// This is in contrast with member operator[], that does not check against bounds.
vector<int> vi(10);
vector<int>::size_type size = vi.size();
unsigned int i = 0;
for (i = 0; i < vi.size(); i++)
{
vi.at(i) = i;
}
show(vi);
cout << "[" << __func__ << "]: ";
for (i = 0; i < size; i++)
{
cout << vi.at(i);
if (i != size - 1)
{
cout << ", ";
}
}
cout << endl;
}
void vec_front()
{
// reference front();
// const_reference front() const;
// Access first element // Returns a reference to the first element in the vector.
vector<int> vi;
vi.push_back(10);
vi.push_back(20);
// now front equals 10, and back 20
vi.front() += vi.back();
print(vi.front()); //30
}
void vec_back()
{
// reference back();
// const_reference back() const;
// Access last element // Returns a reference to the last element in the vector.
vector<int> vi;
vi.push_back(10);
while (0 != vi.back())
{
vi.push_back(vi.back() - 1);
}
show(vi); //10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
}
void vec_assign()
{
// range (1) template <class InputIterator>
// void assign (InputIterator first, InputIterator last);
// fill (2) void assign (size_type n, const value_type& val);
// initializer list (3) void assign (initializer_list<value_type> il); //c++11
// Assign vector content
// Assigns new contents to the vector, replacing its current contents, and modifying its size accordingly.
vector<int> vi1;
vector<int> vi2;
vector<int> vi3;
vi1.assign(6, 8); // (2)
show(vi1); //8, 8, 8, 8, 8, 8
vi2.assign(vi1.begin()+1, vi1.begin()+3); // (1)
show(vi2); //8, 8
int arr[] = {3, 6, 9, 2, 5, 8};
vi3.assign(arr, arr+3); // (3) assign from array
show(vi3); //3, 6, 9
}
void vec_push_back()
{
// void push_back (const value_type& val);
// Add element at the end
// Adds a new element at the end of the vector, after its current last element.
// The content of val is copied (or moved) to the new element.
vector<int> vi;
unsigned int i = 0;
for (i = 0; i <= 9; i++)
{
vi.push_back(i);
}
show(vi); //0, 1, 2, 3, 4, 5, 6, 7, 8, 9
}
void vec_pop_back()
{
// void pop_back();
// Delete last element
// Removes the last element in the vector, effectively reducing the container size by one.
vector<int> vi;
unsigned int i = 0;
for (i = 0; i < 9; i++)
{
vi.push_back(i);
}
show(vi);
while (!vi.empty())
{
cout << "[" << __func__ << "]: pop_back " << vi.back() << endl;
vi.pop_back();
}
}
void vec_insert()
{
// single element (1) iterator insert (iterator position, const value_type& val);
// fill (2) void insert (iterator position, size_type n, const value_type& val);
// range (3) template <class InputIterator>
// void insert (iterator position, InputIterator first, InputIterator last);
// move (4) iterator insert (const_iterator position, value_type&& val); //c++11
// initializer list (5) iterator insert (const_iterator position, initializer_list<value_type> il); //c++11
// Insert elements
// The vector is extended by inserting new elements before the element at the specified position,
// effectively increasing the container size by the number of elements inserted.
vector<int> vi(3, 9);
vector<int>::iterator it;
show(vi); //9, 9, 9
it = vi.begin() + 1;
it = vi.insert(it, 1); // (1)
show(vi); //9, 1, 9, 9
vi.insert(it, 2, 6); // (2)
show(vi); //9, 6, 6, 1, 9, 9
// "it" maybe valid, get a new one
it = vi.begin() + 1;
// If a reallocation happens, all iterators, pointers and references related to the container are invalidated.
// Otherwise, only those pointing to position and beyond are invalidated, with all iterators, pointers and
// references to elements before position guaranteed to keep referring to the same elements they were referring
// to before the call.
vector<int> vi2(2, 7);
vi.insert(it+2, vi2.begin(), vi2.end()); // (3)
show(vi); //9, 6, 6, 7, 7, 1, 9, 9
int arr[] = {0, 1, 2, 3};
vi.insert(vi.begin(), arr, arr+3); // (5)
show(vi); //0, 1, 2, 9, 6, 6, 7, 7, 1, 9, 9
}
void vec_erase()
{
// iterator erase (iterator position);
// iterator erase (iterator first, iterator last);
// Erase elements
// Removes from the vector either a single element (position) or a range of elements ([first,last)).
vector<int> vi;
unsigned int i = 0;
for (i = 0; i <= 9; i++)
{
vi.push_back(i);
}
show(vi); //0, 1, 2, 3, 4, 5, 6, 7, 8, 9
vi.erase(vi.begin() + 8); // (1)
show(vi); //0, 1, 2, 3, 4, 5, 6, 7, 9
vi.erase(vi.begin()+1, vi.begin()+4); // (2)
show(vi); //0, 4, 5, 6, 7, 9
}
void vec_clear()
{
// void clear();
// Clear content
// Removes all elements from the vector (which are destroyed), leaving the container with a size of 0.
vector<int> vi;
unsigned int i = 0;
for (i = 0; i <= 9; i++)
{
vi.push_back(i);
}
show(vi); //0, 1, 2, 3, 4, 5, 6, 7, 8, 9
print(vi.size()); //10
vi.clear();
show(vi); //
print(vi.size()); //0
}
int main() {
vec_construct();
vec_OperatorEQ(); //=
vec_begin_end();
vec_size();
vec_capacity();
vec_empty();
vec_OperatorAT(); //[]
vec_at();
vec_front();
vec_back();
vec_assign();
vec_push_back();
vec_pop_back();
vec_insert();
vec_erase();
vec_clear();
return 0;
}
参考资料
https://blog.csdn.net/fanyun_01/article/details/56842637
https://www.cnblogs.com/Nonono-nw/p/3462183.html
http://www.cplusplus.com/reference/vector/vector/