vector
-
属于顺序容器
-
顺序容器特点:元素并非排序的,元素的插入位置同元素的值无关。常用的有vector,deque,list 三种
-
头文件: < vector>
-
vector通常被认为成一种动态数组或者向量式结构。
其元素在内存连续存放。随机存取任何元素都能在常数时间 完成。在尾端增删元素具有较佳的性能(大部分情况下是常数时间,因为该容器为动态分配内存,在设计此类容器时大多会采用一种预分配内存的策略,从而提升性能,而当在末尾增加元素时预分配的内存如果已经不够就要再分配内存给容器,此时复杂度为O(n))。
创建vector< T >容器
//vector的初始化方法
//1、
vector<int> v1(10);//创建了可容纳10个元素的数组v1
//2、
vector<int> v2(5,20);//创建了包含5个20的数组v2
//3、
vector<unsigned int> primes {2u, 3u, 5u, 7u, 11u, 13u, 17u, 19u};//c++11支持初始化列表
//4、
int a[5] = { 1,2,3,4,5 };
vector<int> v3(a,a+5);
vector<string> words {"one", "two","three", "four", "five"};
vector<string> words_copy(begin(words) , end(words));
//vector<string> words_copy{begin(words) , end(words)};
//初始化列表和构造函数都可以使用这种接受两个迭代器参数的方式来初始化vector数组
vector的大小和容量
vector< T> 对象的大小和容量类型是 vector< T>::size_type(实际上多数情况使用size_t也可以)
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
//vector的容量和大小
vector<size_t> primes { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41 ,43 ,47 };
cout << "The size is " << primes.size() << endl;//size方法表示容器内存在的元素
cout << "The capacity is" << primes.capacity() << endl; //capacity方法表示容器目前的容量
primes.push_back(1);
cout << "The size is " << primes.size() << endl;
cout << "The capacity is" << primes.capacity() << endl;
return 0;
}
结果:
The size is 15
The capacity is15
The size is 16
The capacity is30
resize方法
vector<int> values {1,2,3};
values.resize (5);元素的个数变为参数指定的值,会增加两个用默认值初始化的元素
cout << values[3] << values[4];
values.resize (7, 99);//以第二个参数的值来初始化新增的元素
cout << values[5] << values[6];
结果:
009999
注意,使用resize减少元素个数时不会影响容器容量,对应的reserve() 函数只是改变容量
vector访问现有元素
1、使用[ ]+下标访问,使用规则与数组一致
2、方法.at(下标),基本与[ ]用法一致,不过此方法可以检查数组越界
3、成员函数 front() 和 back() 分別返回序列中第一个和最后一个元素的引用
4、成员函数 data() 返回一个指向数组的指针,它在内部被用来存储元素,一般来说,data() 返回 vector 容器的 T* 类型的值
vector添加和插入
记住,向容器中添加元素的唯一方式是使用它的成员函数。如果不调用成员函数,非成员函数既不能添加也不能删除元素。
-
push_back() 函数(返回值为void),可以在在序列的末尾添加一个元素。(支持移动语义)
-
emplace_back() 的参数是添加到容器中的对象的构造函数所需要的参数。emplace_back()用它的参数作为构造函数的参数,在容器中生成对象(插入对象时比push_back效率高)
std::string str {"alleged"}; words.emplace_back(str, 2, 3); // Create string object corresponding to "leg" in place
emplace_back() 函数会调用接收三个参数的 string 构造函数,生成 string 对象,然后把它添加到 words 序列中。构造函数会生成一个从索引 2 幵始、包含 str 中三个字符的子串。
-
emplace() 可以在 vector序列中插入新的元素。对象会在容器中直接生成,而不是先单独生成对象,然后再把它作为参数传入。
emplace() 的第一个参数是一个迭代器,它确定了对象生成的位置。对象会被插入到迭代器所指定元素的后面。第一个参数后的参数,都作为插入元素的构造函数的参数传入
std::vector<std::string> words {"first", "second"}; // Inserts string(5,'A') as 2nd element auto iter = words.emplace(++std::begin(words),5,'A'); //Inserts string ("$$$$") as 3rd element words.emplace(++iter, "$$$$");
这段代码执行后,vector 中的字符串对象如下:
“first” “AAAAA” “$$$$” “second” -
insert() 可以在 vector 中插入一个或多个元素。第一个参数总是一个指向插入点的 const 或 non-const 迭代器。元素会被迅速插入到第一个参数所指向元素的前面。第一个参数不接受反向迭代器
std::vector<std::string> words { "one","three","eight"} //Vector with 3 elements
-
插入第二个参数指定的单个元素
auto iter = words.insert(++std::begin(words), "two");//此时words序列中的元素为"one" "two" "three" "eight"
返回的迭代器指向被插入的元素 string(”two”)。需要注意的是,在使用同样参数的情况下,调用 insert() 没有调用 emplace() 高效。在 insert() 调用中,构造函数调用 string(“two”) 生成了一个对象,作为传入的第二个参数。在 emplace() 调用中,构造函数用第二个参数直接在容器中生成了字符串对象。
-
插入一个由第二个和第三个参数指定的元素序列
std:: string more[] {"five", "six", "seven" }; iter = words.insert(--std::end(words) , std::begin(more), std::end(more)); //此时/words vector 容器中的字符串对象为:"one" "two" "three" "five" "six" "seven" "eight"
返回的迭代器指向插入的第一个元素"five"
-
在插入点插入多个单个元素。第二个参数是第三个参数所指定对象的插入次数
iter = words.insert(std::cend(words)-1, 2, "nine"); //words vector 容器中的字符串对象如下:"one" "two" "three" "five" "six" "seven" "eight" "nine" "nine" "ten"
返回的迭代器指向插入的第一个元素"nine"
-
在插入点,插入初始化列表指定的元素。第二个参数就是被插入元素的初始化列表
iter = words.insert(std::end(words), {std::string {"twelve"},std::string {"thirteen"}}); //words vector 容器中的字符串对象如下:"one" "two" "three" "five" "six" "seven" "eight" "nine" "nine" "ten" "twelve" "thirteen"
返回的迭代器指向插入的第一个元素"twelve"
-
vector删除元素
-
可以通过使用 vector 的成员函数 clear() 来删除所有的元素,但不会改变其容量
-
可以使用 vector 的成员函数 pop_back() 来删除容器尾部的元素
-
如果要去掉容器中多余的容量,例如不再向容器中添加新元素,那么可以通过使用成 员函数 shrink_to_fit() 来实现
不管这个操作是否依赖 STL 的实现,如果它生效了,那么这个容器现有的迭代器都失效,所以在执行完这个操作后,最好重新获取迭代器。
-
可以使用成员函数 erase() 来删除容器中的一个或多个元素。如果只删除单个元素,那么只需要提供一个迭代器参数
会返回一个迭代器,它指向被删除元素后的一个元素 如果要移除一个元素序列,只需要传入两个迭代器,用来指定移除元素的范围。