c\c++複習基礎要點12---容器vector
容器vector:
1.vector的能力:
vector使用動態陣列實現的,所以元素之間總是存在某種順序,所以vectors是一種有序群集。vector支援隨機存取,因此只要知道位置,你可以在常數時間記憶體取任何元素。
在末端附加或刪除元素時,vector的效能相當好,可是如果你在前端或中部安插或刪除元素,效能就不怎麼樣了,因為操作點之後的每個元素都必須移到另一個位置,而每一次移動都得呼叫賦值操作符。
2.大小和容量:
vector操作大小函式:
size() 返回容器中的元素數量
empty() 判斷容器是否為空(相當於size()==0,但可能但可能更快)
max_size() 返回元素的最大可能數量
例子:
#include<iostream>
#include<vector>
using namespace std;
void main()
{
vector<int> v;
for(inti=0;i<5;i++)
{
v.push_back(i);
}
cout<<"size:"<<v.size()<<endl;
cout<<"max_size:"<<v.max_size()<<endl;
}
執行結果:
size:5
max_size:1073741823
size()函式返回v的元素數量
max_size()函式返回的v容器可能存放的最大元素個數
另外一個與大小有關的函式是capacity(),它返回vector實際能夠容納的元素數量。如果超越這個數量,vector就有必要重新配置內部儲存器(重新分配大小)。
vector的容量之所以很重要,有以下兩個原因:
1. 一旦記憶體重新配置,和vector元素相關的所有引用、指標、迭代器都會失效。
2. 記憶體重新配置很消耗時間。
你可以使用reserve()保留適當容量,避免一再重新配置記憶體。如此一來,只要保留的容量尚有餘裕,就不必擔心引用失效。
std::vector<int> v;
v.reserve(80);
另一種避免重新配置記憶體的方法是,初始化期間就向建構函式傳遞附加引數,構造出足夠的空間。如果你的引數是個數值,它將成為vector的起始大小。
std::vector<T> v(5);
注意:vector不能使用reserve()來縮減容量。如果呼叫reserve()所給的引數比當前vector的容量還小,不會引發任何反應。
vector的操作函式:
1.構造、拷貝和析構:
vector<Elem> c 產生一個空vector,其中沒有任何元素
vector<Elem> c1(c2) 產生另一同型vector副本(所有元素都被拷貝)
vector<Elem> c(n) 利用元素的預設建構函式生成一個大小為n的vector
vector<Elem>c(beg, end) 產生一個vector,以區間[beg,end]做為元素值
c.~vector<Elem> 銷燬所有元素,並釋放記憶體
3. vector支援判斷運算子,==、!=、<、>、<=、>=
4. 賦值
c1 = c2 將c2的全部元素賦值為c1
c.assign(n,elem); 複製n個elem,賦值為c
c.assign(beg ,end); 將區間[beg,end]內的元素賦值為c
c.swap(c2) 將c1和c2元素互換
swap(c1,c2); 同上,此為全域性函式
5. 元素存取:
c.at(idx) 返回索引idx所標示的元素。如果idx越界,丟擲out_of_range
c[idx] 返回索引idx所標示的元素。不進行範圍檢查
c.front() 返回第一個元素。不檢查第一個元素是否存在
c.back() 返回最後一個元素。不檢查最後一個元素是否存在
注:呼叫operator[]時,你必須心裡有數,確定索引有效;呼叫front()、back()時必須確定容器不為空:
例子:
std::vector<Elem>coll; //empty
coll[5]=elem; //error
std::cout<<coll.front(); //error
//不會丟擲異常,因為不檢查
正確方法:
std::vector<Elem>coll; //empty
if(coll.size()>5)
{
coll[5]=elem; //ok
}
if(!coll.empty())
{
cout<<coll.front(); //ok
}
coll.at(5)=elem; //ok throws out_of_range exception
6. 迭代器相關函式
c.begin() 返回一個隨機迭代器,指向第一個元素
c.end() 返回一個隨機迭代器,指向最後元素的下一個位置
c.rbegin() 返回一個逆向迭代器,指向逆向迭代器的第一個元素(最後一個元素)
c.rend() 返回一個逆向迭代器,指向逆向迭代器的最後元素的下一個位置(第一元素的前一個位置)
7. 安插和移除元素:
安插元素和移除元素,都會使得‘作用點’之後的元素的引用、指標、迭代器失效。如果安插操作甚至引發記憶體重新分配,那麼該容器身上的所有引用、指標、迭代器都會失效。
c.insert(pos ,elem); 在pos位置上插入一個elem副本,並返回新元素位置
c.insert(pos ,n,elem); 在pos位置上插入n個elem副本。無返回值
c.insert(pos,beg,end); 在pos位置上插入區間[beg,end]內的所有元素的副本。無返回值
c.push_back(elem); 在尾部新增一個elem副本
c.pop_back(); 移除最後一個元素
c.erase(pos); 移除pos位置上的元素,返回下一個元素的位置
c.erase(beg,end); 移除[beg , end] 區間內的所有元素,返回下一個元素的位置
c.resize(num); 將元素數量改為num(如果size()變大了,多出來的新元素都需要以預設建構函式構造)
c.resize(num,elem);將元素數量改為num(如果size()變大了,多出來的新元素都為elem)
c.clear() 移除所有元素,將容器清空
vector沒有提供任何函式可以直接移除與某值相等的元素
以下語句將其值為val的元素移除:
std::vector<Elem> coll;
……
std::vector<Elem>::iterator pos;
pos =find(coll.begin() , coll.end() , val);
if(pos!=coll.end())
{
coll.erase(pos);
}