1. 程式人生 > >[知識點]C++中STL容器之map

[知識點]C++中STL容器之map

sort函數 gin 操作 ont ack 字符 使用方法 bound 隊列

---恢復內容開始---

一、前言

鑒於最近不少次都要用到map我卻總是出各種bug,於是決定寫一篇總結來鞏固一下。

二、什麽是STL

全稱Standard Template Library,中文名標準模板庫,目的是標準化組件,屬於C++語言的一部分,說白了就是算法的整合包,最常用的例子便是快速排序,在C中你只能老老實實地碼出來,而C++中調用<algorithm>中的sort函數即可。

三、STL容器

STL分為六個部分,這裏重點介紹其中的容器(containers)部分。STL容器本質是一些常用的數據結構的模板,簡化操作。容器分為如下幾種,並列出幾種最常用的:

1、序列式容器(常用:vector/向量)

2、適配器容器(常用:stack/棧,queue/隊列,priority_queue/優先隊列)

3、關聯式容器(常用:set/集合,map/映射)

今天,我們重點介紹map,即映射。

四、map的用途

I miss the taste of the sweeter life...哦對不起串了。

從名字就很好理解作用了——映射,令一物與另一物之間建立起一一映射的關系,以便獲得將不方便查找的信息。

舉個例子,一個很簡單的問題,讀入n個長度為m的字符串,再詢問q次某某字符串是否在其中。初學者選擇字符一一比對,O(nmq);這是有人說,聰明人看到字符串早就去Hash了,可以,but,為保證正確性,哈希值同樣會很大,開一個數組去存怕是無內存上限。

那好,我們將得到的哈希值編一個號,比如某巨大的數我們將它視作1,另一個巨大的數編成2,再把編號與值一一對應的關系給記錄下來,用什麽記錄?

map:正是在下。

五、map的聲明與功能

上面提了,map用途在於自動建立編號與值的對應。那麽STL提供了哪些函數供我們來搗鼓裏面的東西呢?

1、構造

map <int, string> a;

簡單明了,前者為編號,後者為值,此處值為字符串。

2、插入數據

方法一(以pair形式):

a.insert(pair <int, string>(1, "Zhangsan")); 
a.insert(pair <int
, string>(2, "Lisi")); a.insert(pair <int, string>(3, "Wangwu"));

方法二(以value_type形式):

a.insert(map <int, string> :: value_type(1, "Zhangsan"));  

方法三(以數組形式):

a[1] = "Zhangsan";

需要註意的是,方法一二無法覆蓋數據,而方法三可以,即如果編號為1的map已經被映射到“Zhangsan”,可以通過數組形式直接修改。

3、數據遍歷

這裏引入新概念——叠代器。先聲明:

map <int, string>::iterator it; 

使用方法也很簡易:

for (it = a.begin(); it != a.end(); it++)  
   cout << it -> first << ‘ ‘ << it -> second << endl;

這個是前向叠代器,同樣還有反向叠代器,如下:

map <int, string> :: reverse_iterator rit;

for
(rit = a.rbegin(); rit != a.rend(); rit++) cout << rit -> first << ‘ ‘ << rit -> second << endl;

同樣地,還有用數組的方式遍歷:

int s = a.size();
for (int i = 1; i <= s; i++) 
    cout << i <<   << a[i] << endl;

其中,size函數是用來獲取map中有多少項數據。

註意點:在遍歷時我們用了begin()和end(),兩者類型均為叠代器。我們發現遍歷起始點為begin(),當叠代器不等於end()時繼續,這意味著begin()為開頭標識,它包括了數據內容,即第一項數據;end()為結尾標識,但它是最後一項數據後面的一個獨立的標識,本身並不表示任何數據。

4、查找數據

①判斷是否出現用count函數

②判斷出現在哪裏用find函數

map <int, string> :: iterator itx;
itx = map.find(1);
int x = map.count(1);

map <int, string> :: iterator ity;
ity = map.find(4);
int y = map.count(4);

count函數只返回0或1,如上述代碼中,x = 1, y = 0;

find函數返回的是一個叠代器,如上述代碼中,itx -> first = 1, ity -> second = "Zhangsan";

而如果沒有該數據的話,則返回的是it = a.end()(末尾標識)。

5、上界下界(待修改)

lower_bound()返回要查找關鍵字的下界,即值 >= 給定元素的第一個位置,upper_bound()返回上界,即值 > 給定元素的第一個位置。

 1 map <int, int> a;
 2 
 3 int main() {
 4     a[1] = 1, a[2] = 2, a[3] = 3, a[4] = 4;
 5     map <int, int> :: iterator it;
 6     for (int i = 1; i <= 4; i++) {
 7         it = a.lower_bound(i);
 8         printf("%d ", it -> first);
 9     }
10     for (int i = 1; i <= 4; i++) {
11         it = a.upper_bound(i);
12         printf("%d ", it -> first);
13     }
14     return 0;
15 }

輸出結果為“1 2 3 4 2 3 4 4”

6、刪除元素

這裏介紹兩種刪除方法:單刪除,區間刪除。

7、排序問題

六、小結

STL普遍有一個前閉後開的特性,這裏有兩處均能體現:一處是關於begin()和end()的定義,一處是erase()的區間刪除方式,以後應該還會接觸到更多。

平時STL容器用的不是太多,也就queue, priority_queue, map較為常用。算法倒是經常用(algorithm庫),以後有機會再慢慢總結STL的其他部分。

[知識點]C++中STL容器之map