c++中有兩種型別的容器:順序容器
和關聯容器
。順序容器主要有vector、list、deque等。其中vector表示一段連續的記憶體,基於陣列實現,list表示非連續的記憶體,基於鍊錶實現,deque與vector類似,但是對首元素提供插入和刪除的雙向支援。關聯容器主要有map和set。map是key-value形式,set是單值。map和set只能存放唯一的key,multimap和multiset可以存放多個相同的key。
容器類自動申請和釋放記憶體,因此無需new和delete操作。
我們把 vector 稱為容器,是因為它可以包含其他物件
。乙個容器中的所有物件都必須是同一種型別的。
下面介紹部分容器使用詳細: 1
.vector
vector型別得到標準定義為:vectorv1;其中t為型別,這裡可以是內建型別,如int等,也可以是結構體或者類型別。
初始化
vectorv1; //v1是乙個空的vector,它潛在的元素是t型別,執行預設初始化
vectorv2(v1); //v2中包含有v1的所有元素的副本
vectorv2 = v1; //等價於v2(v1),v2中包含有v1所有元素的副本
vectorv3(n, val); //v3包含了n個重複的元素,每個元素的值都是val
vectorv4(n); //v4中包含了n個重複執行了值初始化的物件
vectorv5; //v5包含了初始值個數的元素,每個元素被賦予了相應的初始值
vectorv5 = ; //等價於上面的v5
這裡要區分是
列表初始化
還是值初始化
vectorv1(10); //v1有10個元素,每個元素的值都是0
vectorv2; //v2有1個元素,該元素的值為10
vectorv3(10,1); //v3有10個元素,每個元素的值都是1
vectorv4; //v4有2個元素,值分別為10和1
其他操作
vector
常用操作方法:
vec1.push_back(100); //尾部新增元素
int size = vec1.size(); //元素個數
bool isempty = vec1.empty(); //判斷是否為空
cout《取得第乙個元素
vec1.insert(vec1.end(),5,3); //從
vec1.back
位置插入
5個值為
3的元素
vec1.pop_back(); //刪除末尾元素
vec1.erase(vec1.begin(),vec1.begin()+2);//刪除
vec1[0]-vec1[2]
之間的元素,不包括
vec1[2]
其他元素前移
cout<<(vec1==vec2)?true:false; //判斷是否相等
==、!=、
>=
、<=...
vector::iterator iter = vec1.begin(); //獲取迭代器首位址
vector::const_iterator c_iter = vec1.begin(); //獲取
const
型別迭代器
vec1.clear(); //清空元素
遍歷之一:
下標法
int length = vec1.size();
for(int i=0;i
cout《遍歷之二:迭代器法
vector::iterator iter = vec1.begin();
for(;iter != vec1.end();iter++)
2.list
這裡list和vector基本操作相同,這裡就說說它們之間的區別,便於我們選擇用哪一種容器更好,區別如下:
(1) vector是順序表,表示的是一塊連續的記憶體,元素被順序儲存;list是雙向連線表,在記憶體中不一定連續。
(2)當數值記憶體不夠時,vector會重新申請一塊足夠大的連續記憶體,把原來的資料拷貝到新的記憶體裡面;list因為不用考慮記憶體的連續,因此新增開銷比vector小。
(3)list只能通過指標訪問元素,隨機訪問元素的效率特別低,在需要頻繁隨機訪問元素時,使用vector更加合適。
(4)當向vector插入或者刪除乙個元素時,需要複製移動待插入元素右邊的所有元素;因此在有頻繁插入刪除操作時,使用list更加合適。
注釋:下面介紹乙個list和vector中的插入。
vector中可以使用push_back()向容易的尾端插入指定的資料,但是不能使用push_front,該函式是向容器的首端插入指定的元素,這裡我們就可以使用insert()函式來實現插入操作,insert包括兩個引數,乙個引數是迭代器,用於指出插入元素的位置,這裡即使是尾端迭代器也可以,所以insert完成的是向該迭代器所指位置的前乙個位置插入指定的元素,如:
vectorvec;
listlst;
lst.insert(lst.begin(), "hello"); //向list型別容器的lst的首端插入」hello「
vec.insert(vec.begin(), "hello"); //同上
insert除了上述接收兩個引數的形式外,還可以接收三個引數,如:
vec.insert(vec.begin(), 10, "hello"); //新增10個hello字串到vec的首端
vectorv = ;
vec.insert(vec.begin(), v.end()-2, v.end()); //將v的最後兩個插入vec的首端
lst.insert(lst.end(), ); //將後面的列表中的字串插入lst的尾部
注:迭代器表示要拷貝的範圍,不能指向與目的位置相同的容器,如:
lst.insert(lst.begin(), lst.begin(), lst.end());// 這裡要插入的迭代器容器是lst,但是要拷貝的範圍也是lst,所以執行時會出現錯誤。
3.map
map是屬於關聯容器這一類的,包括兩個引數,第乙個引數是關鍵字,第二個引數的該關鍵字對應的值。
對map的乙個經典例子是單詞計數器程式:
mapword_count; //string 到size_t的空map
string word;
while(cin >> word)
++word_count[word]; //提取word的計數器並將其加1
for(const auto &w : word_count) //使用基於範圍的for語句依次訪問map中的資料
cout << w.first << "occurs" << w.second << ((w.second > 1) ? "times" : "time") << endl;
一般很多時候,我們會將map和set連起來一起用,如下面的例子是改進的上面的單詞計數器的例子,本例子中只統計不在exclude中的單詞
mapword_count;
setexclude = ;
string word;
while(cin >> word)
if (exclude.find(word) == exclude.end())
++word_count[word];
待續......
c 中關聯容器map的使用
補充 使用count,返回的是被查詢元素的個數。如果有,返回1 否則,返回0。注意,map中不存在相同元素,所以返回值只能是1或0。使用find,返回的是被查詢元素的位置,沒有則返回map.end include include include include include using names...
C 標準庫中vector容器的使用
標準stl序列容器 vector string deque和list。標準stl關聯容器 set multiset map和multimap。非標準序列容器slist和rope。slist是乙個單向鍊錶,rope本質上是一 重型 string。非標準的關聯容器hash set hase multis...
C 中map容器的使用說明
c 中map容器提供乙個鍵值對容器,map與multimap差別僅僅在於multiple允許乙個鍵對應多個值.一.map的說明 1.標頭檔案 include 2.定義方法 1 mapm 2 typedef mapm m m 3.插入資料 1 m a 1 2 m.insert map value ty...