STL中的动态数组类
std::vector的特点
- 在数组末尾添加元素所需要的时间是固定的
- 在数组中间添加或是删除元素所需的时间和该元素后面的元素个数成正比
- 存储的元素数是动态的,而vector类负责内存管理
典型的vector操作
实例化vector
#include <vector>
int main ()
{
// vector of integers
std::vector<int> integers;// 使用了默认的构造函数
// 编译器暂时还不支持这种初始化的方法,这是C++11引入的列表初始化
// vector with 3 elements initialized using C++11 list initialization
//std::vector<int> initVector{ 202, 2017, -1 };
// Instantiate a vector with 10 elements (it can still grow)
std::vector<int> tenElements (10); // 使编程人员知道vector至少包含10个元素
// Instantiate a vector with 10 elements, each initialized to 90
std::vector<int> tenElemInit (10, 90);
// Instantiate one vector and initialize it to the contents of another
std::vector<int> copyVector (tenElemInit);// 使用一个vecto实例化另一个vector
// Vector initialized to 5 elements from another using iterators
// 将cbegin()换成begin(),复制vector对象的一部分
std::vector<int> partialCopy (tenElements.begin(),
tenElements.begin() + 5);
return 0;
}
使用push_back()在末尾插入元素
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
vector <int> integers;
// Insert sample integers into the vector:
integers.push_back (50);
integers.push_back (1);
integers.push_back (987);
integers.push_back (1001);
cout << "The vector contains ";
cout << integers.size () << " Elements" << endl;
return 0;
}
用push_back在对象integers的末尾插入元素,最后调用size()方法来检验结果。
列表初始化
C++11通过std::initialize_list<>支持列表初始化,让您能够像处理静态数组那样,在实例化vector的同时初始化其元素。
vector<int> integers = {50, 1, 987, 1001};
//alternatively
vector<int> vecMoreIntegers {50, 1, 987, 1001};
使用insert()在指定位置插入元素
#include <vector>
#include <iostream>
using namespace std;
// for older C++ compilers (non C++11 compliant)
void DisplayVector(const vector<int>& inVec)
{
for (vector<int>::const_iterator element = inVec.begin ();
element != inVec.end ();
++ element )
cout << *element << ' ';
cout << endl;
}
/*
void DisplayVector(const vector<int>& inVec)
{
for(auto element = inVec.cbegin(); // auto and cbegin() are C++11
element != inVec.cend (); // cend() is new in C++11
++ element )
cout << *element << ' ';
cout << endl;
}
*/
int main ()
{
// Instantiate a vector with 4 elements, each initialized to 90
vector <int> integers (4, 90);
cout << "The initial contents of the vector: ";
DisplayVector(integers);
// Insert 25 at the beginning
integers.insert (integers.begin (), 25);
// Insert 2 numbers of value 45 at the end
integers.insert (integers.end (), 2, 45);
cout << "Vector after inserting elements at beginning and end: ";
DisplayVector(integers);
// Another vector containing 2 elements of value 30
vector <int> vecAnother (2, 30);
// Insert two elements from another container in position [1]
integers.insert (integers.begin () + 1,
vecAnother.begin (), vecAnother.end ());
cout << "Vector after inserting contents from another vector: ";
cout << "in the middle:" << endl;
DisplayVector(integers);
return 0;
}
书里面的代码还是很良心的,还考虑到了不支持C++11的老编译器,不错不错!
使用数组的语法访问vector中的元素
#include <iostream>
#include <vector>
int main ()
{
using namespace std;
//vector <int> integers{ 50, 1, 987, 1001 };
vector <int> integers;
integers.push_back(50);
integers.push_back(1);
integers.push_back(987);
integers.push_back(1001);
for (size_t index = 0; index < integers.size (); ++index)
{
cout << "Element[" << index << "] = " ;
cout << integers[index] << endl;
}
integers[2] = 2011; // change value of 3rd element
cout << "After replacement: " << endl;
cout << "Element[2] = " << integers[2] << endl;
return 0;
}
vector中应当是重载了下标运算符,所以可以用[ ]的方式访问vector中的元素。使用[ ]的方式访问vector中的元素时,面临的风险与访问数组元素相同,即不超出容器的边界。更安全的方法是使用成员函数at( )。
// get element at position 2
vector <int> integers;
cout << integers.at(2);
用指针语法访问vector中的元素
#include <iostream>
#include <vector>
int main ()
{
using namespace std;
//vector <int> integers{ 50, 1, 987, 1001 };
vector <int> integers;
integers.push_back(50);
integers.push_back(1);
integers.push_back(987);
integers.push_back(1001);
//这是没有常迭代器?
vector <int>::iterator element = integers.begin ();
// auto element = integers.cbegin (); // same as above, using auto
while (element != integers.end ())
{
size_t index = distance (integers.begin (), element);
cout << "Element at position ";
cout << index << " is: " << *element << endl;
// move to the next element
++ element;
}
return 0;
}
删除vector中的元素
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
void DisplayVector(const vector<T>& inVec)
{
for(vector<int>::const_iterator element = inVec.begin(); // auto & cbegin() are C++11
element != inVec.end (); // cend() is C++11
++ element )
cout << *element << ' ';
cout << endl;
}
int main ()
{
vector<int> integers;
// Insert sample integers into the vector:
integers.push_back (50);
integers.push_back (1);
integers.push_back (987);
integers.push_back (1001);
cout << "Vector contains " << integers.size () << " elements: ";
DisplayVector(integers);
// Erase one element at the end
integers.pop_back ();
cout << "After a call to pop_back()" << endl;
cout << "Vector contains " << integers.size () << " elements: ";
DisplayVector(integers);
return 0;
}
理解vector的大小和容量
#include <iostream>
#include <vector>
int main ()
{
using namespace std;
// Instantiate a vector object that holds 5 integers of default value
vector <int> integers (5);
cout << "Vector of integers was instantiated with " << endl;
cout << "Size: " << integers.size ();
cout << ", Capacity: " << integers.capacity () << endl;
// Inserting a 6th element in to the vector
integers.push_back (666);
cout << "After inserting an additional element... " << endl;
cout << "Size: " << integers.size ();
cout << ", Capacity: " << integers.capacity () << endl;
// Inserting another element
integers.push_back (777);
cout << "After inserting yet another element... " << endl;
cout << "Size: " << integers.size ();
cout << ", Capacity: " << integers.capacity () << endl;
integers.clear();
return 0;
}
实例化一个包含5个整型对象的vector,这些整型对象使用默认值0,它的大小和容量在实例化后相等。这时大小和容量相等,这表明vector的容量已经用完了,再次插入元素将导致vector重新分配其内部缓冲区,复制现有的元素再插入新值。
PS:在重新分配vector内部缓冲区时提前增加容量方面,C++标准没有做任何规定,因此性能的优化程度取决于STL的实现。
STL的deque类
#include <deque>
#include <iostream>
#include <algorithm>
int main ()
{
using namespace std;
// Define a deque of integers
deque<int> intDeque;
// Insert integers at the bottom of the array
intDeque.push_back (3);
intDeque.push_back (4);
intDeque.push_back (5);
// Insert integers at the top of the array
intDeque.push_front (2);
intDeque.push_front (1);
intDeque.push_front (0);
cout << "The contents of the deque after inserting elements ";
cout << "at the top and bottom are:" << endl;
// Display contents on the screen
for (size_t count = 0
; count < intDeque.size ()
; ++ count )
{
cout << "Element [" << count << "] = ";
cout << intDeque [count] << endl;
}
cout << endl;
// Erase an element at the top
intDeque.pop_front ();
// Erase an element at the bottom
intDeque.pop_back ();
cout << "The contents of the deque after erasing an element ";
cout << "from the top and bottom are:" << endl;
// Display contents again: this time using iterators
// if on older compilers, remove auto and uncomment next line
// deque <int>::iterator element;
for (deque <int>::iterator element = intDeque.begin ()
; element != intDeque.end ()
; ++ element )
{
size_t Offset = distance (intDeque.begin (), element);
cout << "Element [" << Offset << "] = " << *element << endl;
}
intDeque.clear();
if (intDeque.empty())
cout << "The container is now empty" << endl;
return 0;
}
deque和vector比起来,它除了尾插,还可以头插。clear()方法可以删除容器中的所有元素。