C++中map和set的使用詳細(xì)攻略
一、set
1.1 set的介紹

首先要知道set的底層是由紅黑樹(平衡二叉搜索樹)實(shí)現(xiàn)的。
Tset存放元素類型,底層是<value, value>的鍵值對。Compare仿函數(shù),因?yàn)閷?shí)現(xiàn)搜索樹需要比較。
1.2 set的使用
1.2.1 set的構(gòu)造
void test_set()
{
// 默認(rèn)構(gòu)造
set<int> s1;
// 迭代器區(qū)間構(gòu)造
int a[] = { 1, 2, 3, 4 };
set<int> s2(a, a + 4);
// 拷貝構(gòu)造(深拷貝)
set<int> s3(s2);
for (int e : s2) cout << e << " ";
cout << endl;
for (int e : s3) cout << e << " ";
cout << endl;
}

1.2.2 set的迭代器

可以看到set有反向迭代器。
void test1()
{
set<int> s;// 排序+去重
s.insert(1);
s.insert(2);
s.insert(3);
s.insert(1);
s.insert(3);
s.insert(4);
// 正向迭代器
set<int>::iterator it1 = s.begin();
while (it1 != s.end())
{
cout << *it1++ << " ";
}
cout << endl;
// 反向迭代器
set<int>::reverse_iterator it2 = s.rbegin();
while (it2 != s.rend())
{
cout << *it2++ << " ";
}
cout << endl;
}

因?yàn)閟et的仿函數(shù)默認(rèn)參數(shù)是less<T>,所以排的是升序,如果我們想排降序就可以傳遞greater<T>。
void test1()
{
set<int, greater<int>> s;// 排序+去重
s.insert(1);
s.insert(2);
s.insert(3);
s.insert(1);
s.insert(3);
s.insert(4);
// 正向迭代器
set<int>::iterator it1 = s.begin();
while (it1 != s.end())
{
cout << *it1++ << " ";
}
cout << endl;
// 反向迭代器
set<int>::reverse_iterator it2 = s.rbegin();
while (it2 != s.rend())
{
cout << *it2++ << " ";
}
cout << endl;
}

1.2.3 set的修改
1.2.3.1 insert && find && erase



void test2()
{
set<int> s;
s.insert(1);
s.insert(2);
s.insert(3);
s.insert(4);
s.insert(5);
set<int>::iterator it = s.find(3);
s.erase(it);
for (auto& e : s)
{
cout << e << " ";
}
cout << endl;
}
1.2.3.2 count

傳進(jìn)去一個(gè)元素?cái)?shù)值,返回該元素的個(gè)數(shù)。
void test2()
{
set<int> s;
s.insert(1);
s.insert(2);
s.insert(3);
s.insert(4);
s.insert(5);
cout << s.count(2) << endl;
cout << s.count(6) << endl;
}

因?yàn)閟et的元素是唯一的,所以在set這里count可以用find來代替,但是在后面的multiset可以插入重復(fù)的元素,count就可以統(tǒng)計(jì)該元素的個(gè)數(shù)。
1.3 multiset
multiset和set的區(qū)別是它可以插入重復(fù)的元素。其他的接口跟set一致。頭文件也跟set相同。
void test3()
{
multiset<int> ms;
ms.insert(1);
ms.insert(1);
ms.insert(2);
ms.insert(3);
ms.insert(4);
for (auto& e : ms)
{
cout << e << " ";
}
cout << endl;
cout << "count(1): " << ms.count(1) << endl;
}

另外使用find查找時(shí),如果有多個(gè)值相同,find返回的值是中序的第一個(gè)。

二、map
2.1 map的介紹

key鍵值對中key的類型T鍵值對中value的類型
注意:
1?? map中的元素總是按照鍵值key進(jìn)行比較排序的。
2?? map支持下標(biāo)訪問符,即在[]中放入key,就可以找到與key對應(yīng)的value。
2.2 map的使用
構(gòu)造和迭代器跟上面的set類似,就不過多闡述。
2.2.1 map的修改
2.2.1.1 insert

void test4()
{
map<string, int> m;
m.insert(pair<string, int>("a", 1));// 匿名對象
m.insert(make_pair("b", 2));// 簡化寫法
m.insert(make_pair("c", 2));
m.insert(make_pair("d", 2));
map<string, int>::iterator it = m.begin();
while (it != m.end())
{
cout << (*it).first << "->" << (*it).second << endl;
it++;
}
}
make_pair:函數(shù)模板,不需要像pair一樣顯示聲明類型,而是通過傳參自動(dòng)推導(dǎo)。

2.2.1.2 統(tǒng)計(jì)次數(shù)
1?? 使用find,利用迭代器
int main()
{
string arr[] = { "北京", "武漢", "廣州", "上海", "北京", "北京", "廣州",
"上海", "上海" };
map<string, int> cnt;
for (auto& e : arr)
{
map<string, int>::iterator fd = cnt.find(e);
if (fd == cnt.end())
{
cnt.insert(make_pair(e, 1));
}
else
{
fd->second++;
}
}
for (auto& e : cnt)
{
cout << e.first << "->" << e.second << endl;
}
return 0;
}

2?? 使用[]
int main()
{
string arr[] = { "北京", "武漢", "廣州", "上海", "北京", "北京", "廣州",
"上海", "上海" };
map<string, int> cnt;
for (auto& e : arr)
{
cnt[e]++;
}
for (auto& e : cnt)
{
cout << e.first << "->" << e.second << endl;
}
return 0;
}

[] 可以用來插入、修改、查找
[] -> (*((this->insert(make_pair(k,mapped_type()))).first)).second
// 等價(jià)于
V& operator[](const K& k)
{
pair<iterator, bool> ret = insert(make_pair(k, V()));
return ret.first->second;
}
這里就可以看出使用[]的時(shí)候要注意:如果沒有它會(huì)直接插入。
所以我們想插入就可以:
int main()
{
map<string, int> m;
// 插入
m["廣西"];
m["廣東"] = 1;
for (auto& e : m)
{
cout << e.first << "->" << e.second << endl;
}
return 0;
}

當(dāng)我們想要修改的時(shí)候不能用insert,因?yàn)?strong>只要key相同就會(huì)插入失敗。
int main()
{
map<string, int> m;
// 插入
m["廣西"];
m["廣東"] = 1;
m.insert(make_pair("廣東", 2));// 插入失敗
for (auto& e : m)
{
cout << e.first << "->" << e.second << endl;
}
return 0;
}
先要修改可以:
m["廣東"] = 2;
key不在就是插入,key在就是查找。
2.3 multimap
int main()
{
multimap<string, int> mm;
mm.insert(make_pair("北京", 1));
mm.insert(make_pair("北京", 2));
mm.insert(make_pair("北京", 1));
mm.insert(make_pair("上海", 1));
for (auto& e : mm)
{
cout << e.first << "->" << e.second << endl;
}
return 0;
}multimap容器與map容器的底層實(shí)現(xiàn)以及成員函數(shù)的接口都是基本一致,而multimap的key可以重復(fù)。注意multimap沒有[]。

使用multimap統(tǒng)計(jì)次數(shù):
int main()
{
multimap<string, int> mm;
string arr[] = { "北京", "武漢", "廣州", "上海", "北京", "北京", "廣州",
"上海", "上海" };
for (auto& e : arr)
{
map<string, int>::iterator fd = mm.find(e);
if (fd == mm.end())
{
mm.insert(make_pair(e, 1));
}
else
{
fd->second++;
}
}
for (auto& e : mm)
{
cout << e.first << "->" << e.second << endl;
}
return 0;
}

補(bǔ)充:set和map的區(qū)別
- map中的元素是key-value(關(guān)鍵字—值)對:關(guān)鍵字起到索引的作用,值則表示與索引相關(guān)聯(lián)的數(shù)據(jù);Set與之相對就是關(guān)鍵字的簡單集合,set中每個(gè)元素只包含一個(gè)關(guān)鍵字。
- set的迭代器是const的,不允許修改元素的值。map允許修改value,但不允許修改key。其原因是因?yàn)閙ap和set是根據(jù)關(guān)鍵字排序來保證其有序性的,如果允許修改key的話,那么首先需要?jiǎng)h除該鍵,然后調(diào)節(jié)平衡,再插入修改后的鍵值,調(diào)節(jié)平衡,如此一來,嚴(yán)重破壞了map和set的結(jié)構(gòu),導(dǎo)致iterator失效,不知道應(yīng)該指向改變前的位置,還是指向改變后的位置。所以STL中將set的迭代器設(shè)置成const,不允許修改迭代器的值;而map的迭代器則不允許修改key值,允許修改value值。
- map支持下標(biāo)操作,set不支持下標(biāo)操作。map可以用key做下標(biāo),map的下標(biāo)運(yùn)算符[ ]將關(guān)鍵碼作為下標(biāo)去執(zhí)行查找,如果關(guān)鍵碼不存在,則插入一個(gè)具有該關(guān)鍵碼和mapped_type類型默認(rèn)值的元素至map中,因此下標(biāo)運(yùn)算符[ ]在map應(yīng)用中需要慎用,const_map不能用,只希望確定某一個(gè)關(guān)鍵值是否存在而不希望插入元素時(shí)也不應(yīng)該使用,mapped_type類型沒有默認(rèn)值也不應(yīng)該使用。如果find能解決需要,盡可能用find。
總結(jié)
到此這篇關(guān)于C++中map和set的使用的文章就介紹到這了,更多相關(guān)C++ map和set的使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C++用一棵紅黑樹同時(shí)封裝出set與map的實(shí)現(xiàn)代碼
- C++使用一棵紅黑樹同時(shí)封裝出map和set實(shí)例代碼
- C++ map與set封裝實(shí)現(xiàn)過程講解
- C++中map和set封裝實(shí)現(xiàn)示例
- C++深入探究哈希表如何封裝出unordered_set和unordered_map
- c++容器list、vector、map、set區(qū)別與用法詳解
- C++ STL入門教程(7) multimap、multiset的使用
- C++中map和set的簡介及使用詳解
- C++中set/multiset與map/multimap的使用詳解
- C++中常見容器類的使用方法詳解(vector/deque/map/set)
- C++實(shí)現(xiàn)map和set封裝詳解
相關(guān)文章
vs2019中使用MFC構(gòu)建簡單windows窗口程序
今天發(fā)現(xiàn)網(wǎng)上好多MFC代碼都不能用,給大家分享一個(gè)簡單的MFC窗口語言,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06
C語言利用數(shù)組和文件實(shí)現(xiàn)登錄注冊功能
這篇文章主要為大家詳細(xì)介紹了C語言利用數(shù)組和文件實(shí)現(xiàn)登錄注冊功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12
Visual Studio 2019安裝使用C語言程序(VS2019 C語言)
這篇文章主要介紹了Visual Studio 2019安裝使用C語言程序,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
詳解C語言數(shù)據(jù)結(jié)構(gòu)之棧
這篇文章主要為大家介紹了C語言數(shù)據(jù)結(jié)構(gòu)之棧,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-01-01
c語言實(shí)現(xiàn)詞頻統(tǒng)計(jì)的簡單實(shí)例
下面小編就為大家?guī)硪黄猚語言實(shí)現(xiàn)詞頻統(tǒng)計(jì)的簡單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-09-09

