1、vector性能
与数组array相似,使用连续的存储位置存储其元素,可以采用常规指针偏移量访问,但是与数组不同,其大小可以动态改变。
与其他动态序列容器(双端队列deques,列表lists和forward_lists)相比,向量vector在访问其元素(就像数组)方面非常有效,并且从其末尾添加或删除元素都相对高效。 但对于涉及在末尾以外的位置插入或删除元素的操作,它们的性能比其他方法差,并且与list和forward_lists相比,迭代器和引用的一致性更差。
2、vector的定义方式
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int>ivector1; //定义了一个空的向量容器
vector<int>ivector2(4, 100); //定义一个向量容器,含有4个元素,每个元素值为100
vector<int>ivector3(ivector2.begin(), ivector2.end());//使用ivector2的迭代器来定义ivector3
vector<int>ivector4(ivector3); //使用ivector3的来定义ivector4
int iarray[] = { 0,1,2,3,4,5,6,6,6,7,8 }; //使用数组来定义ivector
vector<int>ivector(iarray, iarray + sizeof(iarray) / sizeof(int));
cout << "The elements in vector is: ";
for (vector<int>::iterator it = ivector.begin(); it != ivector.end(); it++)
cout << *it << " ";
system("pause");
return 0;
}
(1)assgin(…)函数的用法,类似于copy
int iarray[] = { 0,1,2,3,4,5,6,6,6,7,8 }; //使用数组来定义ivector
vector<int>ivector(iarray, iarray + sizeof(iarray) / sizeof(int));
vector<int>ivector5;
//template <class InputIterator>
//void assign(InputIterator first, InputIterator last);
//两个迭代器指针,分别指向复制开始和结束的地方。
ivector5.assign(ivector.begin() + 1, ivector.end() - 1);
//void assign (size_type n, const value_type& val);
//n指要构造的vector成员的个数,val指成员的数值,他的类型必须与vector类型一致!
vector<int>ivector6;
ivector6.assign(7, 200);
(2)back()函数的用法
注意back()与end()的区别,back返回的是向量容器元素序列的最后一个元素值,而end()指向向量容器元素序列的最后一位的后面,且返回的是一个迭代器指针,不是元素值
vector<int>myvector;
myvector.push_back(10);
while (myvector.back() != 0)
myvector.push_back(myvector.back() - 1);
//输出结果:10 9 8 7 6 5 4 3 2 1 0
(3)begin()函数的用法
返回指向向量中第一个元素的迭代器,与front()不同,front()返回第一个元素的引用,可以直接进行算术运算和输出显示。
用例如下:
// vector::front
#include <iostream>
#include <vector>
int main()
{
std::vector<int> myvector;
myvector.push_back(78);
myvector.push_back(16);
// now front equals 78, and back 16
myvector.front() -= myvector.back();
std::cout << "myvector.front() is now " << myvector.front() << '\n';
//输出结果:myvector.front() is now 62
system("pause");
return 0;
}
同时注意与cbegin()函数的区别:
a.cbegin()返回指向容器中第一个元素的const_iterator,而const_iterator是指向const内容的迭代器。 可以增加和减少此迭代器(除非它本身也是const),就像vector :: begin返回的迭代器一样,**但是即使向量对象本身不是const,也不能用来修改其指向的内容。**即不能修改向量本身的内容。
std::vector<int> myvector1 = { 10,20,30,40,50 };
std::cout << "myvector1 contains:";
for (auto it = myvector1.cbegin(); it != myvector1.cend(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
同时也要注意与rbegin()、rend()的区别:
rbegin()指向的是向量最后一个元素,rend()指向的是向量第一个元素;
// vector::rbegin/rend
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> myvector (5); // 5 default-constructed ints
int i=0;
std::vector<int>::reverse_iterator rit = myvector.rbegin();
for (; rit!= myvector.rend(); ++rit)
*rit = ++i;
std::cout << "myvector contains:";
for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
(4)capacity()函数的用法
返回向量容器的容量,容量有可能等于向量中的元素个数,也有可能大于向量中的元素个数。
vector<int>myvector;
for (int i = 0; i < 100; i++)
myvector.push_back(i);
cout << "the size of myvector is " << myvector.size() << endl;
cout << "the capacity of myvector is " << myvector.capacity() << endl;
cout << "the max_size of myvector is " << myvector.max_size() << endl;
//输出结果:the size of myvector is : 100
//the capacity of myvector is : 128
//the max_size of myvector is : 1073741823
(5)clear()函数
把向量中的所有元素都清空,向量的size为0
(6)crbegin()函数和crend()函数
返回const_reverse_iterator反向开始,即返回指向容器中最后一个元素的const_reverse_iterator(即,它的反向开始)。
std::vector<int> myvector1 = { 10,20,30,40,50 };
std::cout << "myvector1 contains:";
for (auto it = myvector1.crbegin(); it != myvector1.crend(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
//输出结果:50 40 30 20 10
(7)data()函数用法
返回向量内部使用的存储数组的直接指针,通过此指针偏移量,可以直接改变向量内的元素值。
vector<int> myvector2(5);
int *p = data(myvector2);
*p = 20;
p = p + 1;
*p = 30;
p[2] = 100;
for (int i = 0; i < myvector2.size(); i++)
cout << myvector2[i] << endl;
//输出结果:20 30 0 100 0
(8)emplace()函数
通过在指定位置上插入元素,起到扩展容器的作用。由于向量使用数组作为其基础存储,因此在向量末端以外的位置插入元素会导致容器将位置之后的所有元素都移动一个到其新位置。与其他类型的序列容器(例如list或forward_list)执行的操作相比,这通常是一种低效的操作。有关直接在最后扩展容器的成员函数,请参见emplace_back。
返回值是指向新插入元素的迭代器。
vector<int>ivector = { 10,20,30 };
vector<int>::iterator it;
it = ivector.emplace(ivector.begin() + 1,100);//emplace()返回的是当前插入元素的位置
ivector.emplace(it, 200);
ivector.emplace(ivector.end(), 300);
//输出结果是:10 200 100 20 30 300
(9)emplace()函数
在向量的末尾插入元素,功能类似push_back()
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> myvector = {10,20,30};
myvector.emplace_back (100);
myvector.emplace_back (200);
std::cout << "myvector contains:";
for (auto& x: myvector)
std::cout << ' ' << x;
std::cout << '\n';
return 0;
}
(10)empty()函数
判断向量是否为空,如果向量为空,即size为0,返回true;如果向量不为空,则返回false;
(11)erase()函数
擦除向量中的元素,可以使指定的单个元素,也可以是一个范围内的元素,参数为向量迭代器,如(ivector.begin()+3)或(ivector.begin(),ivector.begin()+3)
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int>ivector = { 10,20,30 };
vector<int>::iterator it;
it = ivector.emplace(ivector.begin() + 1,100);//emplace()返回的是当前插入元素的位置
ivector.emplace(it, 200);
ivector.emplace(ivector.end(), 300);
//输出结果是:10 200 100 20 30 300
cout << "The elements in myvector is: ";
for (vector<int>::iterator it = ivector.begin(); it != ivector.end(); it++)
cout << *it << " ";
cout << endl;
ivector.erase(ivector.begin() + 3);
ivector.erase(ivector.begin(), ivector.begin() + 3);//擦除vector容器中前3个元素
cout << "The elements in myvector is: ";
for (vector<int>::iterator its = ivector.begin(); its != ivector.end(); its++)
cout << *its << " ";
//输出结果为30 300
system("pause");
return 0;
}
(12)get_allocator()
返回与向量关联的分配器对象的副本。
// vector::get_allocator
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> myvector;
int * p;
unsigned int i;
// allocate an array with space for 5 elements using vector's allocator:
p = myvector.get_allocator().allocate(5);
// construct values in-place on the array:
for (i=0; i<5; i++) myvector.get_allocator().construct(&p[i],i);
std::cout << "The allocated array contains:";
for (i=0; i<5; i++) std::cout << ' ' << p[i];
std::cout << '\n';
// destroy and deallocate:
for (i=0; i<5; i++) myvector.get_allocator().destroy(&p[i]);
myvector.get_allocator().deallocate(p,5);
//The allocated array contains: 0 1 2 3 4
return 0;
}
(13) insert()函数
a.插入单个元素 single element,注意其返回值是迭代器
iterator insert (iterator position, const value_type& val);//格式
vector<int> myvector(2, 300);
vector<int>::iterator it = myvector.begin();
it = myvector.insert(it, 200);//返回值是迭代器
b.插入多个相同元素,无返回值
vector<int> myvector(2, 300);
vector<int>::iterator it = myvector.begin();
//it = myvector.insert(it, 200);
//void insert (iterator position, size_type n, const value_type& val);
myvector.insert(it, 2, 400);
c.插入一个范围的元素range
//template <class InputIterator>
//void insert (iterator position, InputIterator first, InputIterator last);
vector<int> myvector(2, 300);
vector<int>::iterator it = myvector.begin();
it = myvector.insert(it, 200);
myvector.insert(it, 2, 400);
//此时it已经不再有效,需要一个新的
it = myvector.begin();//如果没有这句代码的话程序会报错
vector<int> anothervector(2, 400);
myvector.insert(it + 2, anothervector.begin(), anothervector.end());
int myarray[] = { 501,502,503 };
myvector.insert(myvector.begin(), myarray, myarray + 3);
//输出结果:501 502 503 400 400 400 400 200 300 300
(14)push_back()和pop_back()
一个是从尾部压入元素,一个是从尾部弹出元素
// vector::pop_back
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> myvector;
int sum (0);
myvector.push_back (100);
myvector.push_back (200);
myvector.push_back (300);
while (!myvector.empty())
{
sum+=myvector.back();
myvector.pop_back();
}
std::cout << "The elements of myvector add up to " << sum << '\n';
return 0;
}
(15)vector重载了“=”和“[]”,因此可以使用如下语句:
// vector assignment
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> foo (3,0);
std::vector<int> bar (5,0);
bar = foo;
foo = std::vector<int>();
std::cout << "Size of foo: " << int(foo.size()) << '\n';
std::cout << "Size of bar: " << int(bar.size()) << '\n';
return 0;
}
for (int i = 0; i < myvector.size(); i++)
cout << myvector[i] << " ";
(16)reserve()函数
格式:void reserve (size_type n);
若当前向量的容量小于n时,则使用这个函数可以使向量扩容至n.
(17) resize()函数
原型:void resize (size_type n, value_type val = value_type());
调整容器的大小,使其包含n个元素。
如果n小于当前容器的大小,则将内容减少到其前n个元素,并删除超出范围的元素(并销毁它们)。
如果n大于当前容器的大小,则通过在末尾插入任意数量的元素以达到n的大小来扩展内容。 如果指定了val,则新元素将初始化为val的副本,否则将对其进行值初始化。
如果n也大于当前容器容量,则会自动重新分配已分配的存储空间。
(18)shrink_to_fit()函数
要求容器减少其容量以适合其尺寸。即使用后capacity=size;
// vector::shrink_to_fit
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> myvector (100);
std::cout << "1. capacity of myvector: " << myvector.capacity() << '\n';
myvector.resize(10);
std::cout << "2. capacity of myvector: " << myvector.capacity() << '\n';
myvector.shrink_to_fit();
std::cout << "3. capacity of myvector: " << myvector.capacity() << '\n';
return 0;
}
(19)swap()函数
两个向量交换
// swap vectors
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> foo (3,100); // three ints with a value of 100
std::vector<int> bar (5,200); // five ints with a value of 200
foo.swap(bar);
std::cout << "foo contains:";
for (unsigned i=0; i<foo.size(); i++)
std::cout << ' ' << foo[i];
std::cout << '\n';
std::cout << "bar contains:";
for (unsigned i=0; i<bar.size(); i++)
std::cout << ' ' << bar[i];
std::cout << '\n';
return 0;
}
(20)也可以通过“<”、=“”、“>”、“<=”、“>=”等比较向量的关系
由此,对STL中向量的学习告一段落。