std:map使用筆記

本人是多年的C碼農(nóng),最近才開始玩C++,所以難免會(huì)遇到C++里很平常普通的東西,在C程序員眼里已經(jīng)灰常神奇了。
舉個(gè)例子,最普通的鏈表,在C里面要構(gòu)建一個(gè)鏈表,要解決的幾個(gè)問(wèn)題:

  1. 每個(gè)節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)
  2. 節(jié)點(diǎn)的插入、刪除問(wèn)題,以及由此產(chǎn)生的內(nèi)存問(wèn)題
  3. 鏈表的表頭,表尾問(wèn)題
  4. 特定節(jié)點(diǎn)的查找,匹配
  5. 鏈表的遍歷,排序問(wèn)題
  6. 等等

上面列舉的是鏈表操作的幾個(gè)基本問(wèn)題,但是在C里面要自己構(gòu)建一個(gè)好用且不出錯(cuò)的鏈表,并且把以上基本操作都實(shí)現(xiàn),估計(jì)也得花一番好功夫。
C++就不一樣了,C++提供一個(gè)STL(標(biāo)準(zhǔn)模板類)庫(kù),這個(gè)里面有個(gè)std::map模板類,是一個(gè)關(guān)聯(lián)式容易,簡(jiǎn)單理解為,鏈表里的每個(gè)節(jié)點(diǎn)都是一個(gè)<key, value>對(duì)。
現(xiàn)在就來(lái)看下它是如何減輕碼農(nóng)痛苦的。


一.建一張表

看到這個(gè)問(wèn)題,C碼農(nóng)是不是馬上就要想,哎呀,那我要:

  1. 先設(shè)計(jì)一個(gè)數(shù)據(jù)節(jié)點(diǎn),并設(shè)計(jì)成鏈表節(jié)點(diǎn);
  2. 然后再不斷的malloc新節(jié)點(diǎn);
  3. 再依次把這些節(jié)點(diǎn)串接起來(lái),形成一張表。

把上面這幾點(diǎn)用code實(shí)現(xiàn)并調(diào)通,那就是個(gè)合格的C程序員。
但是我們來(lái)看看用STL提供的模板類有多么方便。
直接上代碼:

sample 1

#include<map>
#include<string>
#include<iostream>
using namespace std;

int main()
{
    // 聲明一張表
    map<string,int>  myMap;     
    
    // 依次給這張表添加元素
    myMap["a"]=1;                       
    myMap["b"]=2;
    myMap["c"]=3;
    
    // 遍歷剛剛建的表
    map<string,int>::iterator it;
    for(it=myMap.begin(); it!=myMap.end(); ++it)
        cout<<"key: "<<it->first <<" value: "<<it->second<<endl;
    
    return   0;
}

這段code輸出為:

key: a value: 1
key: b value: 2
key: c value: 3

哇,是不是有點(diǎn)神奇了,建一張表,以及遍歷這張表,這么簡(jiǎn)單!
怎么看起來(lái)像C的數(shù)組?
其實(shí)不是,其實(shí)是這個(gè)模板類重載了操作符[ ], 讓你看起來(lái)覺得像數(shù)組而已;
這個(gè)有點(diǎn)點(diǎn)誤導(dǎo),我覺得比較純正的還是insert方法,再看下一段code:

sample 2

#include<map>
#include<string>
#include<iostream>
using namespace std;

int main()
{
    map<string,int>  myMap;             // 聲明一張表

    // 依次給這張表添加元素
    myMap.insert(pair<string, int>("a", 1));    
    myMap.insert(pair<string, int>("b", 2));
    myMap.insert(pair<string, int>("c", 3));

    // 遍歷剛剛建的表
    map<string,int>::iterator it;
    for(it=myMap.begin(); it!=myMap.end(); ++it)
        cout<<"key: "<<it->first <<" value: "<<it->second<<endl;
    return   0;
}

這次看起來(lái)有點(diǎn)正兒八經(jīng)的鏈表插入的感覺了吧:)
用上C++提供的標(biāo)準(zhǔn)模板庫(kù),有不有點(diǎn)從石器時(shí)代跨入青銅時(shí)代的感覺~~~


二. 刪除節(jié)點(diǎn)

既然有增加節(jié)點(diǎn),那么對(duì)應(yīng)地,就有刪除節(jié)點(diǎn)。
我們先回顧一下C怎么考慮這個(gè)問(wèn)題的:

  1. 在鏈表中找到特定的節(jié)點(diǎn)。
  2. 把這個(gè)節(jié)點(diǎn)從鏈表中斷開,把這個(gè)節(jié)點(diǎn)的相鄰節(jié)點(diǎn)鏈上。
  3. free掉這個(gè)節(jié)點(diǎn)。

裹筋吧,我們看看std:map是怎么讓人happy的。
看代碼:

sample 3

#include<map>
#include<string>
#include<iostream>
using namespace std;

int main()
{
    map<string,int>  myMap;             // 聲明一張表

    // 依次給這張表添加元素
    myMap.insert(pair<string, int>("a", 1));    
    myMap.insert(pair<string, int>("b", 2));
    myMap.insert(pair<string, int>("c", 3));

    // 遍歷剛剛建的表
    map<string,int>::iterator it;
    for(it=myMap.begin(); it!=myMap.end(); ++it)
        cout<<"key: "<<it->first <<" value: "<<it->second<<endl;

    cout << endl;

    // 刪掉一個(gè)節(jié)點(diǎn)
    myMap.erase("b");
    map<string,int>::iterator iter;
    for(iter=myMap.begin(); iter!=myMap.end(); ++iter)
        cout<<"key: "<<iter->first <<" value: "<<iter->second<<endl;
    return   0;
}

刪除特定節(jié)點(diǎn)?free廢節(jié)點(diǎn)?自動(dòng)就幫你做了!


三. 清空map

清空操作為什么單獨(dú)拿出來(lái)說(shuō)一下,是因?yàn)槲业谝淮问褂靡卜噶隋e(cuò)誤,因?yàn)樽钊菀紫氲降姆椒ň褪牵罕闅v這個(gè)表,one by one地刪除每一個(gè)節(jié)點(diǎn)。
請(qǐng)看錯(cuò)誤代碼:

map<string,int>::iterator iter;
for(iter=myMap.begin(); iter!=myMap.end(); ++iter) {
    myMap.erase(iter);
}

這其實(shí)是錯(cuò)誤的寫法,因?yàn)閑rase會(huì)釋放掉iter,然后執(zhí)行++iter,程序就回跑飛。
所以這里附上一個(gè)推薦的寫法:

map<string,int>::iterator iter;
for(iter=myMap.begin(); iter!=myMap.end(); ) {
    // erase() 返回的是下一個(gè)元素的迭代器 
    iter = myMap.erase(iter);
}

或者再簡(jiǎn)單一點(diǎn):

myMap.clear();

世界清凈了~ 讓我歇會(huì)兒,喝口茶。


四. 幾個(gè)經(jīng)常用的方法

Item Description
begin() 返回指向map頭部的迭代器
clear() 刪除所有元素
empty() 判斷map是否為空
end() 返回指向map末尾的迭代器
erase() 刪除一個(gè)元素
find() 查找一個(gè)元素
insert() 插入元素
size() 返回map中元素的個(gè)數(shù)

還有其他的就不一一列舉了,還有就是要注意這些方法的重載版本,用的時(shí)候可以特別研究一下。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容