1. 程式人生 > >STL中基本容器區別

STL中基本容器區別

在STL中基本容器有: string、vector、list、deque、set、map

set 和map都是無序的儲存元素,只能通過它提供的介面對裡面的元素進行訪問

set:集合, 用來判斷某一個元素是不是在一個組裡面,使用的比較少
map:對映,相當於字典,把一個值對映成另一個值,如果想建立字典的話使用它好了

string、vector、list、deque、set 是有序容器 
1.string 

string 是basic_string<char> 的實現,在記憶體中是連續存放的.為了提高效率,都會有保留記憶體,如string s= "abcd",這時s使用的空間可能就是255, 當string再次往s裡面新增內容時不會再次分配記憶體.直到內容>255時才會再次申請記憶體,因此提高了它的效能.


當內容>255時,string會先分配一個新記憶體,然後再把內容複製過去,再複製先前的內容.

對string的操作,如果是新增到最後時,一般不需要分配記憶體,所以效能最快;
如果是對中間或是開始部分操作,如往那裡新增元素或是刪除元素,或是代替元素,這時需要進行記憶體複製,效能會降低.

如果刪除元素,string一般不會釋放它已經分配的記憶體,為了是下次使用時可以更高效.

由於string會有預保留記憶體,所以如果大量使用的話,會有記憶體浪費,這點需要考慮.還有就是刪除元素時不釋放過多的記憶體,這也要考慮.

string中記憶體是在堆中分配的,所以串的長度可以很大,而char[]是在棧中分配的,長度受到可使用的最大棧長度限制.


如果對知道要使用的字串的最大長度,那麼可以使用普通的char[],實現而不必使用string.
string用在串長度不可知的情況或是變化很大的情況.

如果string已經經歷了多次新增刪除,現在的尺寸比最大的尺寸要小很多,想減少string使用的大小,可以使用:
string s = "abcdefg";
string y(s); // 因為再次分配記憶體時,y只會分配與s中內容大一點的記憶體,所以浪費不會很大
s.swap(y); // 減少s使用的記憶體

如果記憶體夠多的話就不用考慮這個了 


capacity是檢視現在使用記憶體的函式
大家可以試試看string分配一個一串後的capacity返回值,還有其它操作後的返回值


2.vector 

vector就是動態陣列.它也是在堆中分配記憶體,元素連續存放,有保留記憶體,如果減少大小後記憶體也不會釋放.如果新值>當前大小時才會再分配記憶體 
對最後元素操作最快(在後面新增刪除最快 ), 此時一般不需要移動記憶體,只有保留記憶體不夠時才需要
對中間和開始處進行新增刪除元素操作需要移動記憶體,如果你的元素是結構或是類,那麼移動的同時還會進行構造和析構操作,所以效能不高(最好將結構或類的指標放入vector中,而不是結構或類本身,這樣可以避免移動時的構造與析構)。
訪問方面,對任何元素的訪問都是O(1),也就是是常數的,所以vector常用來儲存需要經常進行隨機訪問的內容,並且不需要經常對中間元素進行新增刪除操作.

相比較可以看到vector的屬性與string差不多,同樣可以使用capacity看當前保留的記憶體,使用swap來減少它使用的記憶體.

總結
需要經常隨機訪問請用vector 

3.list 

list就是連結串列,元素也是在堆中存放,每個元素都是放在一塊記憶體中 
list沒有空間預留習慣,所以每分配一個元素都會從記憶體中分配,每刪除一個元素都會釋放它佔用的記憶體,這與上面不同,可要看好了

list在哪裡新增刪除元素效能都很高,不需要移動記憶體,當然也不需要對每個元素都進行構造與析構了,所以常用來做隨機操作容器.
但是訪問list裡面的元素時就開始和最後訪問最快
訪問其它元素都是O(n) ,所以如果需要經常隨機訪問的話,還是使用其它的好

總結
如果你喜歡經常新增刪除大物件的話,那麼請使用list
要儲存的物件不大,構造與析構操作不復雜,那麼可以使用vector代替
list<指標>完全是效能最低的做法,這種情況下還是使用vector<指標>好,因為指標沒有構造與析構,也不佔用很大記憶體 


4.deque 

雙端佇列,也是在堆中儲存內容的.它的儲存形式如下:

[堆1]
...
[堆2]
...
[堆3]

每個堆儲存好幾個元素,然後堆和堆之間有指標指向,看起來像是list和vector的結合品,不過確實也是如此
deque可以讓你在前面快速地新增刪除元素,或是在後面快速地新增刪除元素,然後還可以有比較高的隨機訪問速度

vector是可以快速地在最後新增刪除元素,並可以快速地訪問任意元素
list是可以快速地在所有地方新增刪除元素,但是隻能快速地訪問最開始與最後的元素
deque在開始和最後新增元素都一樣快,並提供了隨機訪問方法,像vector一樣使用[]訪問任意元素,但是隨機訪問速度比不上vector快,因為它要內部處理堆跳轉
deque也有保留空間.另外,由於deque不要求連續空間,所以可以儲存的元素比vector更大,這點也要注意一下.還有就是在前面和後面新增元素時都不需要移動其它塊的元素,所以效能也很高