详解map、multimap、unordered_map、unordered_multimap
来源:互联网 发布:nba官方旗舰店 淘宝 编辑:程序博客网 时间:2024/05/16 15:33
详解map、multimap、unordered_map、unordered_multimap
相信有不少同学和我一样刚接触C++ STL,被其深深吸引。但是想弄懂每个模板类不是一个容易事。大家应该对vector、list、stack、queue等类比较了解了,所以今天详细介绍下几个很常用很强大但有点不太好懂的类map、multimap、unordered_map、unordered_multimap。乍一看都差不多都是什么map,但这肯定有所不同。下面就在一个一个讲解的同时,让大家了解这四个类的使用,以及不同之处。
map
1) 从一个简单的例子开始
2) #include<map>
3) #include<iostream>
4) using namespace std;
5)
6) int main()
7) {
8) map<char,int> msi;
9) //map::operator[]
10) msi['x'] = 3;
11) msi['z'] = 3;
12) msi['g'] = 2;
13) msi['y'] = 1;
14) //map::at()
15) auto beg = msi.begin();
16) for(; beg !=msi.end();beg++){
17) cout<<msi.at(beg->first)<<" ";
18) }
19) cout<<endl;
20) return 1;
21) }
结果:
2 3 1 3
代码分析:
l map::operator[]
mapped_type& operator[] (const key_type& k);
mapped_type& operator[] (key_type&& k);
该函数通过调用mak_pair函数将k,v作为一个kv对,在通过insert函数按照k将v插入map中。
l map::at
mapped_type& at (const key_type& k);
const mapped_type& at (const key_type& k) const;
该函数通过k来找到v值。
l 从结果看出,打印是按照k值递增来打印v值的。
2) 从例子1)继续
我们对例子1中的代码进行下修改。
1) #include<map>
2) #include<iostream>
3) using namespace std;
4)
5) int main()
6) {
7) map<char,int> msi;
8) //map::operator[]
9) msi['x'] = 3;
10) msi['x'] = 4; //这里修改了
11) msi['g'] = 2;
12) msi['y'] = 1;
13) //map::at()
14) auto beg = msi.begin();
15) for(; beg !=msi.end();beg++){
16) cout<<msi.at(beg->first)<<" ";
17) }
18) cout<<endl;
19) return 1;
20) }
结果:
2 4 1
代码分析:
l 这里出现了重复key值x,那么是不是x/3对就被覆盖了呢????因此只打印出2 41!!!!!
3) 从例子2)继续
1) int main()
2) {
3) map<char,int> msi;
4) //map::operator[]
5) msi['x'] = 3;
6) msi['x'] = 4;
7) msi['g'] = 2;
8) msi['y'] = 1;
9) //map::at()
10) auto beg = msi.begin();
11) for(; beg !=msi.end();beg++){
12) cout<<msi.at(beg->first)<<" ";
13) }
14) cout<<endl;
15)
16) auto get = msi.equal_range('x');
17) auto skbeg = get.first;
18) auto skend = get.second;
19) for(; skbeg!=skend; skbeg++){
20) cout<<skbeg->first<<":"<<skbeg->second<<" ";
21) }
22) cout<<endl;
23)
24) return 1;
25) }
结果:
2 4 1
x:4
代码分析:
l map::equal_range
pair<const_iterator,const_iterator> equal_range (const key_type& k) const;
pair<iterator,iterator> equal_range (const key_type& k);
按照reference中的意思这个函数应该是返回包含k的element的上下界,但是我们并没有打印出,x:3 x:4。所以呢,嗯我们得出一个结论在map中k和v是一对一的关系,不能出现一个k对应多个v值的情况。
4) OK继续
1) int main()
2) {
3) map<char,int> msi;
4) //map::operator[]
5) msi['c'] = 3;
6) msi['h'] = 5;
7) msi['b'] = 2;
8) msi['a'] = 1;
9)
10) //insert g
11) msi.insert(pair<char,int>('g',4));
12) //copy map
13) map<char,int> newmap;
14) newmap.insert(msi.begin(), msi.find('g'));
15) //map::at()
16) auto beg = msi.begin();
17) for(; beg !=msi.end();beg++){
18) cout<<beg->first<<"->"<<msi.at(beg->first)<<" ";
19) }
20) cout<<endl;
21)
22) auto newbeg = newmap.begin();
23) for(; newbeg !=newmap.end();newbeg++)
24) cout<<newbeg->first<<"->"<<newmap.at(newbeg->first)<<" ";
25) cout<<endl;
26) /*auto get = msi.equal_range('x');
27) auto skbeg = get.first;
28) auto skend = get.second;
29) for(; skbeg!=skend; skbeg++){
30) cout<<skbeg->first<<":"<<skbeg->second<<" ";
31) }*/
32)
33) cout<<endl;
34)
35) return 1;
36) }
结果:
a->1 b->2 c->3 g->4 h->5
a->1 b->2 c->3
代码分析:
l map::insert
template <class P> pair<iterator,bool> insert (P&& val);
template <class InputIterator>
void insert (InputIterator first, InputIterator last);
这里分别使用了这两种insert函数,其中第一个我们将一个pair对象作为一个element存入map;第二个我们将msi中从开始到g以前的element存入了newmap中。
4) TBC
还有些没有介绍到的成员函数,我想就在另外几个类中介绍吧,其实都很简单…
multimap
1) 直奔主题
1) #include<map>
2) #include<iostream>
3) #include<string>
4) using namespace std;
5)
6) bool cmp(const string &a, const string &b)
7) {
8) return a.compare(b)>0?true:false;
9) }
10)
11) int main()
12) {
13) bool (*cmp_pt) (const string&, const string&) = cmp;
14) multimap<string, int, bool(*) (const string&, const string&)> mci(cmp_pt); //降序
15) mci.insert(pair<string,int>("bb",2));
16) mci.insert(pair<string,int>("aa",1));
17) mci.insert(pair<string,int>("cc",3));
18) mci.insert(pair<string,int>("gg",6));
19) mci.insert(pair<string,int>("cc",5));//重复
20)
21) auto beg = mci.begin();
22) for(;beg!=mci.end();beg++){
23) cout<<beg->first<<"->"<<beg->second<<" ";
24) }
25) cout<<endl;
26) auto skget = mci.equal_range("cc");
27) auto skbeg = skget.first;
28) auto skend = skget.second;
29) for(;skbeg!=skend;skbeg++ )
30) cout<<skbeg->first<<"->"<<skbeg->second<<" ";
31) cout<<endl;
32) }
结果:
gg->6 cc->3 cc->5 bb->2 aa->1
cc->3 cc->5
代码分析:
l 降序输出
这里有两种方法,一种是函数指针,一种是类。这里采用的前者。类方法更加简单,只需要重载operator()即可,如下所示。
struct classcomp {
bool
operator() (
constchar
& lhs,
const
char& rhs)
const
{
return lhs<rhs;}
};
std::multimap<char,int,classcomp> fourth;
l 初始化数据
数据不能通过operator[]给予喽~,没这个成员函数。
l 重点来了
可以发现尽管加入了重复键值cc/5,但是打印的时候我们依然输出了重复的键值对,因此我们可以说multimap和map的一个最大的区别就是,multimap可以实现一对多的存储方式!!!!!!!!
unordered_multimap
1) 依然直奔主题
1) #include<iostream>
2) #include<unordered_map>
3) using namespace std;
4)
5) int main()
6) {
7) unordered_multimap<char,int> umci,insertum={ {'b',12},{'w',11} };
8) umci.insert(make_pair('d',5));
9) umci.insert(pair<char,int>('a',1));
10) umci.insert(make_pair('b',2));
11) umci.insert(make_pair('g',8));
12) umci.insert(insertum.begin(),insertum.end());
13)
14) auto beg = umci.begin();
15) for(;beg!=umci.end();beg++)
16) cout<<beg->first<<"->"<<beg->second<<" ";
17) cout<<endl;
18)
19) return 1;
20) }
结果:
g->8 b->12 b->2 w->11 a->1 d->5
代码分析:
l 无序存储
可以明显的看出unordered_multimap的无序存储特点,这是其与multimap最大的区别。
- 详解map、multimap、unordered_map、unordered_multimap
- map/multimap/unordered_map/unordered_multimap; set/multiset/unordered_set/unordered_multiset
- STLmap、multimap、unordered_map、unordered_multimap差异
- STL中map,multimap,set,multiset,unordered_map,unordered_multimap,unordered_set,unordered_multiset的实现方法
- STL中map,multimap,set,multiset,unordered_map,unordered_multimap,unordered_set,unordered_multiset的实现方
- set、unordered_set、unordered_multiset、map、unordered_map、unordered_multimap
- map,multimap,unordered_map,set,multiset,unordered_set
- STL中map,unordered_map,multimap的区别
- [STL] map,multimap,unordered_map基本用法
- map和multimap 详解
- map/multimap用法详解
- std::map, std::multimap, std::tr1::unordered_map 区别
- STL set multiset map multimap unordered_set unordered_map example
- 关联容器(map、set、multimap、multiset、pair、unordered_map)
- STL:map/multimap用法详解
- STL:map/multimap用法详解
- unordered_map & map
- <map>\<unordered_map>
- 《移动互联网下婚恋APP:应围绕“婚姻”做闭环》文章有感
- 菜单(一)
- pat 1087
- 高精度除法
- cocos2d-x lua中class的定义
- 详解map、multimap、unordered_map、unordered_multimap
- C++私有继承实现has-a关系
- hdu 1162 Eddy's picture 最小生成树入门题 Prim+Kruskal两种算法AC
- 【struts框架】第一节Action-NameSpace定义
- EEPROM组件
- 【struts框架】第一节Action-路径问题与创建Action方法
- 我理解的JAVA学习流程
- C语言指针疑难杂症
- HDU 3586 Information Disturbing 二分+树形DP