1. 程式人生 > >C++進階(語法篇)—第9章 STL(補)

C++進階(語法篇)—第9章 STL(補)

9.3關聯容器

關聯容器中的元素是按關鍵字來儲存和訪問的;而順序容器中的元素是按照它們在容器中的位置來順序儲存和訪問的。—<< C++ Primer>>

關聯容器常用的有map、set、multimap、multiset。

9.3.1 map

關聯容器map是關鍵字—值的集合,如map<int,string> is_map。物件is_map中儲存的元素必須是2個數值,一個int型別的key值(即關鍵字),一個是string型別的value值,其順序是key放在value之前。key值是無法修改的,而value值是可以修改的,可以通過is_map的迭代器it->first訪問key值,it->second訪問value值。

使用關聯容器map必須包含標頭檔案map和使用名稱空間std。

//map的初始化

#include <iostream>

#include <map>

#include <string>

 

using namespace std;

 

int main(int argc, char ** argv)

{

//初始化1:宣告+賦值

map<int, string> is_map1;

is_map1 =

 { {1,"string1"},{2,"string2"},{3,"string3"} };

 

//初始化2:C++11的列表初始化

map<int, string> is_map2 = { {1,"my_string1"},{2,"my_string2"},{3,"my_string3"} };

 

//初始化3:用map物件來初始化

map<int, string> is_map3(is_map1);

 

//初始化4:用map的迭代器來初始化

map<int, string> is_map4(is_map2.begin(), is_map2.end());

 

map<int, string>::iterator it;

for (it = is_map1.begin(); it != is_map1.end(); it++)

cout << it->first << ": " << it->second << endl;//it後必須使用箭頭,才會索引出first和second

 

return 0;

}

執行結果:

1: string1

2: string2

3: string3

map常用的迭代器:iterator、const_iterator、reverse_iterator、const_reverse_iterator,對應的迭代器函式是begin/end()、rbegin/rend()、cbegin/cend()、crbegin/crend(),其具體用法和string一樣。

//map容器函式的使用

#include <iostream>

#include <map>

#include <string>

 

using namespace std;

 

int main(int argc, char ** argv)

{

 

map<int, string> is_map;

is_map = { {1,"string1"},{2,"string2"},{3,"string3"} };

 

//map容器插入元素的3種方法

//方法1:insert-pair

is_map.insert(pair<int,string>(4,"string4"));

//方法2:insert-value_type

is_map.insert(map<int, string>::value_type(5,"string5"));

 

//方法3:操作符[]

is_map[6] = "string6";//返回key為6的value值引用

//方法1和方法2不可以重新插入相同key值的元素,其本質是插入

//方法3可以重賦值相同key值的元素,其本質是賦值

 

//insert的其他用法

auto it = is_map.find(3);

is_map.insert(it, pair<int, string>(8, "string8"));

is_map.insert({ {7,"string7"},{10,"string10"},{9,"string9"} });

 

for (auto it = is_map.begin(); it != is_map.end(); it++)

cout << it->first << ": " << it->second << endl;

 

//erase的用法

cout << "刪除key為6和9的元素" << endl;

auto iter = is_map.find(6);

is_map.erase(iter);

is_map.erase(9);

for (auto it = is_map.begin(); it != is_map.end(); it++)

cout << it->first << ": " << it->second << endl;

 

return 0;

}

執行結果:

1: string1

2: string2

3: string3

4: string4

5: string5

6: string6

7: string7

8: string8

9: string9

10: string10

刪除key為6和9的元素

1: string1

2: string2

3: string3

4: string4

5: string5

7: string7

8: string8

10: string10

以下列出了map容器常用的函式:

操作符[]:map[k]返回key值為k的元素value引用。

at():map.at(k)返回key值為k的元素value引用,若可不存在,丟擲out_of_range。

size():返回map中元素的個數,即key-value的個數。

max_size():由於儲存空間的限制,返回map中可以容納的最大元素數。

empty():如果map為空,返回0;不為空,返回1。

clear():清除容器中所有的元素。

find():find(k)表示在map中查詢key為的元素,若有則返回指向它的迭代器;若沒有則返回 end迭代器。

count():統計map中key為k的元素個數,若是map,返回1表示存在,返回0表示不存 在。

erase():

(1)iterator erase(const_iterator position):刪除迭代器指向的內容;

(2)size_type erase(const key_type &k):刪除key為k的元素,返回刪除的數目,對於map, 成功刪除返回1,k不存在則返回0;

(3) iterator erase(const_iterator first, const_iterator last):刪除迭代器範圍內的內容。

insert():

(1)pair<iterator, bool> insert(const pair<key, value> &val):單個元素插入,引數為pair型別;(2)iterator insert(const_iterator pos, const pair<key, value> &val):從pos指定的位置開始查詢key-value應該插入的位置;

(3)void insert(initializer_list<value_type> il):初始化列表插入。

multimap是關鍵字允許重複的map,用法基本相同,不再多述。

9.3.2 set

set和map相同點:不允許出現2個相同的key值;內部的元素都會根據元素的key值自動排序。

set和map不同點:map容器有key值(關鍵字)和value值;set容器只有key值,即關鍵字就是值。

使用關聯容器set必須包含標頭檔案set和使用名稱空間std。

//set初始化

#include <iostream>

#include <set>

#include <string>

 

using namespace std;

 

int main(int argc, char ** argv)

{

//初始化1:宣告+賦值

set<string> ss1;

ss1 = {"this","is","string"};

//初始化2:C++11列表初始化

set<string> ss2 = { "this","is","my_string" };

//初始化3:使用set的迭代器初始化

set<string> ss3(ss1.begin(),ss1.end());

//初始化4:使用set物件初始化

set<string> ss4(ss2);

 

for (auto it = ss4.begin(); it != ss4.end(); it++)

cout << *it << endl;

 

return 0;

}

執行結果:

is

my_string

this

set常用的迭代器:iterator、const_iterator、reverse_iterator、const_reverse_iterator,對應的迭代器函式是begin/end()、rbegin/rend()、cbegin/cend()、crbegin/crend(),其具體用法和string一樣。

//set常用函式

#include <iostream>

#include <set>

#include <string>

 

using namespace std;

 

int main(int argc, char ** argv)

{

 

set<string> ss;

ss = {"this","is","string"};

ss.insert("hello");

auto it = ss.find("is");

ss.erase(it);

ss.erase("this");

 

for (auto it = ss.begin(); it != ss.end(); it++)

cout << *it << endl;

 

return 0;

}

執行結果:

hello

string

set容器常用函式:size()、max_size()、clear()、empty()、erase()、insert()、count()、find()、erase()、insert()。除了insert之外,其他函式的用法都和map容器中的用法一致,但是需要注意的是set容器沒有操作符[]和at()函式。

insert(key_value):將key_value插入到容器set中 ,返回值是pair<set<int>::iterator,bool>。bool表示插入是否成功;iterator代表插入的位置。若key_value已經在set中,則iterator表示的key_value在set中的位置。

multiset是關鍵字允許重複的set,用法基本相同,不再多述。

9.4容器介面卡

STL提供了3中容器介面卡:stack、queue、priority_queue。注:介面卡不支援迭代器。

stack堆疊是一個後進先出的線性表,插入元素(入棧)和刪除元素(出棧)都在棧頂進行,另一端稱為棧底。使用stack,必須包含標頭檔案stack和使用名稱空間std。

#include <iostream>

#include <stack>

#include <vector>

#include <string>

 

using namespace std;

 

int main(int argc, char ** argv)

{

//初始化一個int型堆疊

stack<int> si;

//初始化一個vector<string>型堆疊,stack第一個引數必須和vector中的資料型別相同

stack<string, vector<string>> s_vs;

 

if (si.empty())

cout << "stack is empty" << endl;

else

cout<< "stack is not empty" << endl;

si.push(1);

si.push(2);

si.push(5);

si.push(6);

si.push(1);

si.pop();

cout << "si.top():" << si.top()<<endl;

cout << "si.size():" << si.size() << endl;

 

return 0;

}

執行結果:

stack is empty

si.top():6

si.size():4

stack只支援push()、pop()、empty()、top()、size()等函式;並且stack只能一個一個入棧,不能使用列表初始化。

queue是一個先進先出的線性表,只能在隊尾插入元素,在隊首刪除元素。使用queue,必須包含標頭檔案queue和使用名稱空間std。

queue的初始化和stack的初始化方法一樣。

queue支援的函式有push()、pop()、empty()、size()、front()、back()。

priority_queue不再多述。