vector 是一種順序容器,可以看作是可以改變大小的數(shù)組。
就像數(shù)組一樣届榄,vector 占用連續(xù)的內(nèi)存地址來(lái)存儲(chǔ)元素,因此可以像數(shù)組一樣用偏移量來(lái)隨機(jī)訪問(wèn)倔喂,但是它的大小可以動(dòng)態(tài)改變铝条,容器會(huì)自動(dòng)處理內(nèi)存分配問(wèn)題。
在內(nèi)部席噩,vector 使用動(dòng)態(tài)分配的數(shù)組來(lái)存儲(chǔ)元素班缰,當(dāng)新元素插入時(shí),如果現(xiàn)有的存儲(chǔ)空間已經(jīng)占滿悼枢,則需要重新再分配一個(gè)新的數(shù)組埠忘,并且將之前的元素都移動(dòng)到新的內(nèi)存上。這個(gè)過(guò)程是非常耗時(shí)的,因此莹妒,vector 并不會(huì)在每次插入新元素時(shí)都重新分配內(nèi)存名船。
相反,vector 容器可能會(huì)分配一些額外的內(nèi)存來(lái)適應(yīng)其大小的增長(zhǎng)动羽,因此包帚,其真實(shí)容量可能比存儲(chǔ)這些元素實(shí)際需要的內(nèi)存要大。庫(kù)通過(guò)不同的策略來(lái)平衡內(nèi)存占用和空間再分配运吓,但無(wú)論如何渴邦,空間分配只應(yīng)在 vector 大小以對(duì)數(shù)增長(zhǎng)的時(shí)候發(fā)生,以便在向量末尾插入單個(gè)元素可以做到均攤情況下是常數(shù)級(jí)的時(shí)間復(fù)雜度拘哨。
因此谋梭,相對(duì)于數(shù)組,vector 會(huì)消耗更多的內(nèi)存來(lái)?yè)Q取更有效地對(duì)內(nèi)存進(jìn)行管理并且動(dòng)態(tài)增長(zhǎng)倦青。
相對(duì)于其他動(dòng)態(tài)容器瓮床,vector 支持隨機(jī)訪問(wèn),并且能相對(duì)高效地在末尾插入或者刪除元素产镐,但如果要在其他位置插入或者刪除元素隘庄,vector 就會(huì)表現(xiàn)得很差,而且迭代器和引用也不是那么方便癣亚。
構(gòu)造函數(shù)
explicit vector (const allocator_type& alloc = allocator_type());
默認(rèn)構(gòu)造函數(shù)丑掺,構(gòu)造出一個(gè)不包含任何元素的空的 vector;explicit vector (size_type n);
構(gòu)造出一個(gè)包含個(gè)元素的 vector述雾,默認(rèn)會(huì)初始化為 0街州;
explicit vector (size_type n, const value_type& val, const allocator_type& alloc = allocator_type());
構(gòu)造出一個(gè)包含個(gè)值為
的 vector;
vector (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type());
構(gòu)造出一個(gè)包含迭代器范圍內(nèi)元素的 vector玻孟,注意左閉右開(kāi)唆缴;
vector (const vector& x);
復(fù)制構(gòu)造函數(shù),構(gòu)造出一個(gè)和相同的 vector黍翎;
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
vector<int> first; // 空的 vector
vector<int> second (4, 100); // 包含 4 個(gè)值為 100 元素的 vector面徽,[100, 100, 100, 100]
vector<int> third (second.begin(), second.end()); // 包含 second 起始迭代器到終止迭代器區(qū)間元素的 vector,[100, 100, 100, 100]
vector<int> fourth (third); // 對(duì) third 的復(fù)制玩敏,[100, 100, 100, 100]
// 數(shù)組也可以用來(lái)作為迭代器初始化 vector
int myints[] = {16, 2, 77, 29};
vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) ); //[16, 2, 77, 29]
vector<int> sixth (4); // [0, 0, 0, 0]
cout << "The contents of fifth are:";
for (vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it)
cout << ' ' << *it;
cout << '\n';
return 0;
}
賦值運(yùn)算
賦值運(yùn)算會(huì)給容器賦予新的內(nèi)容斗忌,替換掉舊的內(nèi)容,同時(shí)改變其大小旺聚。
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
vector<int> foo (3,0);
vector<int> bar (5,0);
bar = foo;
foo = vector<int>();
cout << "Size of foo: " << int(foo.size()) << '\n'; // 0
cout << "Size of bar: " << int(bar.size()) << '\n'; // 3
return 0;
}
迭代器
-
iterator begin();
返回指向 vector 中第一個(gè)元素的迭代器织阳; -
iterator end();
返回一個(gè)迭代器,引用向量容器中的 past-the-end 元素砰粹,也即最后一個(gè)元素之后的理論元素唧躲; -
reverse_iterator rbegin();
返回指向 vector 中最后一個(gè)元素的反向迭代器造挽,增加反向迭代器會(huì)使它們向前移動(dòng); -
reverse_iterator rend();
返回一個(gè)反向迭代器弄痹,指向向量中第一個(gè)元素之前的理論元素饭入;
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
vector<int> myvector;
for(int i = 0; i < 5; i++)
{
myvector.push_back(i);
}
vector<int>::iterator it = myvector.begin();
for (; it != myvector.end(); it++)
{
cout << *it << '\t';
}
cout << endl;
vector<int>::reverse_iterator rit = myvector.rbegin();
for (; rit != myvector.rend(); rit++)
{
cout << *rit << '\t';
}
cout << endl;
return 0;
}
// 0 1 2 3 4
// 4 3 2 1 0
也可以對(duì)向量建立指針,然后通過(guò)指針來(lái)訪問(wèn)成員函數(shù)肛真⌒扯或者建立引用。
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
vector<int> myvector;
for(int i = 0; i < 5; i++)
{
myvector.push_back(i);
}
vector<int> *p = &myvector;
p->push_back(5);
vector<int>::reverse_iterator rit = p->rbegin();
// vector<int>::reverse_iterator rit = (*p).rbegin();
for (; rit != p->rend(); rit++)
{
cout << *rit << '\t';
}
cout << endl;
vector<int> &ref_myvector = myvector;
ref_myvector.push_back(6);
vector<int>::iterator it = ref_myvector.begin();
for (; it != ref_myvector.end(); it++)
{
cout << *it << '\t';
}
cout << endl;
return 0;
}
// 5 4 3 2 1 0
// 0 1 2 3 4 5 6
容量
-
size_type size() const;
返回向量中元素的個(gè)數(shù)蚓让; -
size_type max_size() const;
返回向量中最大可能包含的元素個(gè)數(shù)乾忱,但這只是理論上的; -
void resize (size_type n, value_type val = value_type());
重新設(shè)置向量的大小使之包含個(gè)元素历极;如果
小于現(xiàn)有向量大小窄瘟,則只保留前
個(gè)元素;如果
大于現(xiàn)有向量大小趟卸,那么在末尾插入元素來(lái)使向量大小達(dá)到
蹄葱;如果
大于現(xiàn)有向量容量,那么會(huì)自動(dòng)重新分配內(nèi)存锄列;
-
size_type capacity() const;
返回向量當(dāng)前分配的內(nèi)存可以包含多少個(gè)元素图云; -
bool empty() const;
返回當(dāng)前向量是否為空,也就是大小是否為零邻邮; -
void reserve (size_type n);
讓向量當(dāng)前分配的內(nèi)存至少可以包含個(gè)元素琼稻;
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
vector<int> myvector;
cout << "max_size: " << myvector.max_size() << endl;
// 添加元素的過(guò)程中容量會(huì)不斷增大
for(int i = 0; i < 10; i++)
{
myvector.push_back(i);
cout << "size: " << myvector.size() << '\t';
cout << "capacity: " << myvector.capacity() << endl;
}
vector<int> othervector;
othervector.reserve(100);
// 添加元素的過(guò)程中大小不超過(guò) 100 就不會(huì)增大
for(int i = 0; i < 10; i++)
{
othervector.push_back(i);
cout << "size: " << othervector.size() << '\t';
cout << "capacity: " << othervector.capacity() << endl;
}
return 0;
}
元素訪問(wèn)
-
reference operator[] (size_type n);
像數(shù)組一樣訪問(wèn)位置處的元素,但不會(huì)進(jìn)行邊界檢測(cè)饶囚;
-
reference at (size_type n);
訪問(wèn)位置處的元素,但會(huì)進(jìn)行邊界檢測(cè)鸠补;
-
reference front();
返回向量中第一個(gè)元素的引用萝风; -
reference back();
返回向量中最后一個(gè)元素的引用;
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
vector<int> myvector;
for(int i = 0; i < 10; i++)
{
myvector.push_back(i);
}
cout << myvector.front() << endl;
cout << myvector.back() << endl;
// 此處越界訪問(wèn)向量紫岩,不會(huì)提示
for(int i = 0; i <= myvector.size(); i++)
{
cout << myvector[i] << '\t';
}
cout << endl;
// 此處越界訪問(wèn)向量规惰,會(huì)拋出一個(gè) out_of_range 異常
for(int i = 0; i <= myvector.size(); i++)
{
cout << myvector.at(i) << '\t';
}
cout << endl;
return 0;
}
向量修改
-
void assign (InputIterator first, InputIterator last);
給向量重新分配迭代器范圍內(nèi)的元素,注意左閉右開(kāi)泉蝌;
-
void assign (size_type n, const value_type& val);
給向量重新分配個(gè)值
的元素歇万;
-
void push_back (const value_type& val);
在向量末尾添加一個(gè)元素; -
void pop_back();
從向量末尾刪除一個(gè)元素勋陪; -
iterator insert (iterator position, const value_type& val);
在迭代器位置前面插入一個(gè)元素贪磺,返回指向第一個(gè)新插入元素的迭代器; -
void insert (iterator position, size_type n, const value_type& val);
在迭代器位置前面插入個(gè)值
的元素诅愚;
-
void insert (iterator position, InputIterator first, InputIterator last);
在迭代器位置前面插入迭代器范圍內(nèi)的元素寒锚;
-
iterator erase (iterator position);
刪除迭代器位置的元素,返回最后一個(gè)被刪除元素的后面一個(gè)元素的迭代器; -
iterator erase (iterator first, iterator last);
刪除迭代器范圍內(nèi)的元素刹前,返回最后一個(gè)被刪除元素的后面一個(gè)元素的迭代器泳赋;
-
void swap (vector& x);
和向量進(jìn)行交換,兩個(gè)向量元素類型相同喇喉,但大小可能不同祖今;
-
void clear();
清空向量;
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
vector<int> first;
vector<int> second;
vector<int> third;
first.assign(7, 100); // [100, 100, 100, 100, 100, 100, 100]
vector<int>::iterator it;
it = first.begin() + 1;
second.assign(it, first.end() - 1); // [100, 100, 100, 100, 100]
int myints[] = {1776, 7, 4};
third.assign(myints, myints + 3); // [1776, 7, 4]
cout << "Size of first: " << int (first.size()) << '\n';
cout << "Size of second: " << int (second.size()) << '\n';
cout << "Size of third: " << int (third.size()) << '\n';
vector<int> myvector (3, 100); // [100, 100, 100]
it = myvector.begin() + 1;
it = myvector.insert(it, 200); // [100, 200, 100, 100]拣技,此時(shí) it 指向新插入的元素 200
myvector.insert(it, 2, 300); // [100, 300, 300, 200, 100, 100]千诬,此時(shí) it 無(wú)效了
it = myvector.begin();
vector<int> anothervector (2, 400); // [400, 400]
myvector.insert(it + 2, anothervector.begin(), anothervector.end());
// [100, 300, 400, 400, 300, 200, 100, 100]
int myarray [] = {501, 502, 503};
myvector.insert (myvector.begin(), myarray, myarray + 3);
// [501, 502, 503, 100, 300, 400, 400, 300, 200, 100, 100]
cout << "myvector contains:";
for (it = myvector.begin(); it < myvector.end(); it++)
cout << ' ' << *it;
cout << '\n';
myvector.clear();
for (int i = 1; i <= 10; i++) myvector.push_back(i);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
it = myvector.erase(myvector.begin() + 5);
// [1, 2, 3, 4, 5, 7, 8, 9, 10],此時(shí) it 指向 6 后面的元素 7
it = myvector.erase(myvector.begin(), myvector.begin() + 3);
// [4, 5, 7, 8, 9, 10]过咬,此時(shí) it 指向 3 后面的元素 4
cout << "myvector contains:";
for (unsigned i = 0; i < myvector.size(); ++i)
cout << ' ' << myvector[i];
cout << '\n';
return 0;
}
參考資料 [http://www.cplusplus.com]
獲取更多精彩大渤,請(qǐng)關(guān)注「seniusen」!