【STL记录】Containers--Vectors

让人想犯罪 __ 提交于 2019-12-27 18:26:11

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

Vector类似于一个动态数组

使用vector,需加入头文件:

#include <vector>

一、Abilities of Vectors

Vector复制所有元素到它的内部动态数组中。通常这些元素是有一定顺序的,因此vector是一种有序集合。

Vector提供随机访问,如果知道元素的位置,可以直接访问元素。

当在尾部插入和删除元素时,vector表现很好;但在中间或前端插入、删除元素时,则较慢。

1.Size and Capacity

    Vector除了提供常用的操作size(),empty(),和max_size(),还提供了一个capacity()函数,用来返回一个vector在它的实际内存中所包含的元素个数。一旦超出了这个capacity,vector将从新分配它的内部内存。

capacity的重要性有两个方面:

  • 再分配(reallocation)使得vector的引用,指针和iterators都失效
  • 再分配(reallocation)需要花费一定时间

 为了避免再分配(reallocation),可以使用reserve()函数来确保capacity:

vector<int> v;    //create an empty vector
v.reserve(80);    //reserve memory for 80 elements

调用reserve()并不能收缩容量(capacity)。如果调用reserve()的参数小于当前的capacity,那么这个操作是no-op。

如果没有调用reserve()设置容量,在插入数据前,将分配一块内存(例如2K)来存放数据,这样就会造成内存浪费。

C++11介绍了一个新的函数:a nonbinding request to shrink the capacity to fit the current number of elements

v.shrink_to_fit();  //request to shrink memory

2.Constructors and destructor of vector

Table 1.Constructors and destructor
Operation Effect
 vector<Elem> c Default constructor:创建一个空的vector
 vector<Elem> c(c2) Copy constructor:通过复制c2创建c
 vector<Elem> c = c2 Copy constructor:通过复制c2创建c
 vector<Elem> c(rv) Move constructor:creates a new vector,taking the contents of the rvalue rv
 vector<Elem> c = rv Move constructor:creates a new vector,taking the contents of the rvalue rv
 vector<Elem> c(n) 使用默认构造函数创建一个有n个元素的vector
 vector<Elem> c(n, elem) 创建一个有n个元素的vector,并且使用elem初始化
 vector<Elem> c(beg, end) 创建一个使用范围[beg,end)初始化的vector
 vector<Elem> c(initList) 创建一个使用initList初始化的vector
 vector<Elem> c = initList 创建一个使用initList初始化的vector
 c.~vector() 销毁所有元素并释放内存

二、Vector Operations

1.Nonmodifying Operations

Operation Effect
 c.empty() 返回容器是否为空(相当于size() == 0)
 c.size() 返回当前元素的个数
 c.max_size() 返回可能存在元素的最大个数
 c.capacity() 返回没有再分配的元素的最大个数
 c.reserve(num) 扩展capacity
 c.shrink_to_fit() 收缩capacity,适应元素个数
 c1 == c2 返回c1是否等于c2
 c1 != c2 返回c1是否不等于c2
 c1 < c2 返回c1是否小于c2
 c1 > c2 返回c1是否大于c2
 c1 <= c2 返回c1是否小于等于c2
 c1 >= c2 返回c1是否大于等于c2

2.Assignments 

Operation Effect
 c = c2 将c2所有的元素赋给c
 c = rv Move assigns all elements of the rvalue rv to c
 c = initList 将initList赋给c
 c.assign(n, elem) 将值val赋给c的每一个元素
 c.assign(beg, end) 将[beg,end)范围的值分配给c
 c.assign(initList) 将initList的值分配给c
 c1.swap(c2) 交换c1和c2的数据
 swap(c1, c2) 交换c1和c2的数据

 3.Element Access

Operation Effect
 c[idx] 返回索引为idx的元素(没有边界检查)
 c.at(idx) 返回索引为idx的元素(当idx超出边界,抛出range-error异常)
 c.front() 返回第一个元素(不检查第一个元素是否存在)
 c.back() 返回最后一个元素(不检查最后一个元素是否存在)

 4.Inserting and Removing Elements

Insert and Remove Operations
Operation Effect
 c.push_back(elem) 将elem附加到末尾
 c.pop_back() 移除最后一个元素,不返回
 c.insert(pos, elem) 将elem插入到pos之前的位置,并返回新元素的位置
 c.insert(pos, n, elem) 在pos之前的位置开始插入n个elem,并返回新插入的第一个元素的位置
 c.insert(pos, beg, end) 将[beg, end)的值插入到从pos之前的位置,并返回第一个新元素的位置
 c.insert(pos, initlist) 将initlist的值插入到从pos之前的位置,并返回第一个新元素的位置
 c.emplace(pos, args...) 将args插入到pos之前的位置,并返回第一个新元素的位置
 c.emplace_back(args...) 将args附加到末尾
 c.erase(pos) 移除pos所指的元素,并返回下一个元素位置
 c.erase(beg, end) 移除范围[beg,end)的元素,并返回下一个元素的位置
 c.resize(num) 设置元素个数为num,如果增长了,使用默认构造函数初始化
 c.resize(num, elem) 设置元素个数为num,如果增长了,使用elem初始化
 c.clear() 移除所有元素

例如,移除第一个元素:

vector<Elem> coll;
...
//remove first element with value val
vector<Elem>::iterator pos;
pos = find(coll.begin(), coll.end(), val);
if(pos != coll.end()) {
    coll.earse(pos);
}

三、Example of Using Vector

#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<iterator>
using namespace std;

int main()
{
	//create empty vector for stirng
	vector<string> sentence;
	
	//reserve memory for elements to avoid reallocation
	sentence.reserve(5);
	
	//append some element
	sentence.push_back("Hello,");
	sentence.insert(sentence.end(), { "how", "are", "you", "?"});
	
	//print elements separated with spaces
	copy(sentence.cbegin(), sentence.cend(),
	     ostream_iterator<string>(cout, "  "));
	cout << endl;
	
	//print "technical data"
	cout << "max_size(): " << sentence.max_size() << endl;
	cout << "size(): " << sentence.size() << endl;
	cout << "capacity(): " << sentence.capacity() << endl;
	
	//swap second and fourth element
	swap(sentence[1], sentence[3]);
	
	//insert element "always" before element "?"
	sentence.insert(find(sentence.begin(), sentence.end(), "?"), "always");
	
	//assign "!" to the last element
	sentence.back() = "!";
	
	//print elements separated with space
	copy(sentence.cbegin(), sentence.cend(),
	     ostream_iterator<string>(cout, " "));
	cout << endl;
	
	//print some technical data again
	cout << "size(): " << sentence.size() << endl;
	cout << "capacity(): " << sentence.capacity() << endl;
	
	//delete last two elements
	sentence.pop_back();
	sentence.pop_back();
	//shrink capacity 
	sentence.shrink_to_fit();
	
	//print some technical data again
	cout << "size(): " << sentence.size() << endl;
	cout << "capacity(): " << sentence.capacity() << endl;
	
}

输出:

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!