STL Associative Containers Types:map、set、multimap、mutilset以及对应的unordered类型
来源:互联网 发布:乐乎的图片怎么保存 编辑:程序博客网 时间:2024/06/08 05:26
相信有不少同学和我一样刚接触C++ STL,被其深深吸引。但是想弄懂每个模板类不是一个容易事。大家应该对vector、list、stack、queue等类比较了解了,所以今天详细介绍下几个很常用很强大但有点不太好懂的类map、multimap、unordered_map、unordered_multimap。乍一看都差不多都是什么map,但这肯定有所不同。下面就在一个一个讲解的同时,让大家了解这四个类的使用,以及不同之处。
关于map史上最详细使用方法说明,请点击:点击打开链接
http://blog.csdn.net/u010025211/article/details/46653675
八种容器的不同:
map:关联容器,保存键值对(key-value),不能有重复的键,有序,例如如果是string类型,则按字母表顺序
set:键即是值,没有pair
multimap:和map对应,区别是key可以重复出现多次
mutilset:和set对应,区别是key可以重复出现多次
unordered_map:map organised by a hash function,无序
unordered_set : set organised by a hash function,
unordered_multimap: Hased map; key can appear mutiple times;
unordered_mutiset: hashed set; key can appear mutiple times;
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!!!!!
如果不是用[],而是用insert插入,那么输出应为 2 3 1,map不能有重复键
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() (
const
char& 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最大的区别。
- STL Associative Containers Types:map、set、multimap、mutilset以及对应的unordered类型
- C++ unordered Associative Containers(C++11)
- 【STL】STL中红黑树的应用set、multiset、map、multimap
- STL associative containers(关联容器)
- 数据结构::关于STL中map,set,muliset,multimap要说的
- Effective STL 20 Specify comparison types for associative containers of pointers
- STL map, multimap, set, multiset 函数介绍
- STL容器 set、 multiset、map、multimap
- C++ STL之 map\set\multimap\multiset
- Associative Containers
- stl的set,multiset, map, multimap, deque, list, stack, queue, priority_queue
- STL中hashtable,hashset,hashmap,set,map,multiset和multimap的区别
- STL中map,multimap,set,multiset,unordered_map,unordered_multimap,unordered_set,unordered_multiset的实现方法
- STL中hashtable,hashset,hashmap,set,map,multiset和multimap的区别
- STL中map,multimap,set,multiset,unordered_map,unordered_multimap,unordered_set,unordered_multiset的实现方
- C++STL中,map/multimap,set/multiset 和vector的排序
- STL关联容器MAP、SET与multimap、multiset与hashmap、hashset的区别
- STL Containers之map
- 黑马程序员--OC--分类和重新定义description方法
- 一些支持向量机(SVM)的开源代码库的链接及其简介
- web前端兼容问题
- gcc 源码包下载地址
- mapReduce 求交集---并集---
- STL Associative Containers Types:map、set、multimap、mutilset以及对应的unordered类型
- WebService到底是什么?
- Visual Studio 2013 错误
- leetcode之 median of two sorted arrays
- State Machines with C Callbacks
- MapReduce的模式、算法和用例
- 【转】unity5 animation 如何实现pingpong效果
- LR经典面试题
- cuda并行编程之求解ConjugateGradient(共轭梯度迭代)丢失dll解决方案