C++学习STL之关联容器 --- pair、map、set

本博文我们继续讨论标准模板库STL的关联容器;

主要有:pair、map、set。

一:pair

pair是一种简单的关联类型,不属于容器范围。而是代表一个 key-value键值对。

创建、初始化、操作 示例代码如下:

 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 using namespace std;
 5 //将pair放入容器&initpair
 6 int main(int argc, const char *argv[])
 7 {
 8     vector<pair<string, int> > vec;//初始化vector
 9
10     pair<string, int> p1;//num.1
11     p1.first = "hello";
12     p1.second = 12 ;
13     vec.push_back(p1);
14
15     pair<string, int> p2("world", 22);//num.2
16     vec.push_back(p2);
17
18     vec.push_back(make_pair<string, int>("foo", 44));//num.3
19
20     for(vector<pair<string,int> >::iterator it = vec.begin(); //g++ main.cc -std=c++0x
21         it != vec.end();
22         ++it)
23     {
24         cout << "key: " << it->first << "  val:"<< it->second << endl;
25     }
26
27     return 0;
28 }

二:map

1):map则是一个容器,里面存储的是 pair对象。但存储的方式与vector<pair>这种 连续存储有所不同, map采用的是 二叉排序树存储pair,一般是红黑树。

2):map使用下标访问时,如果 key不存在,那么会在map 中自动添加一个新的pair,value为默认值。

性能分析:由于map采用二叉排序树(红黑树),树的高度不超过 [logN] +1。所以 插入和查询时间复杂度 为  O(lgN);

注意:使用insert插入map元素时,如果失败,则不会更新原来的值。

a):初始化(示例代码如下):

 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 #include <map>
 5 #include <algorithm>
 6 using namespace std;
 7 //Red_black Tree
 8 int main(int argc, const char *argv[])
 9 {
10     map<string, int> m;
11     m["beijing"] = 2000;
12     m["hangzhou"] = 880;
13     m["shanghai"] = 1500;
14 // key --> value  采用二叉排序树对key排序
15 //两种打印方式
16     for(map<string, int>::const_iterator it = m.begin();
17         it != m.end();
18         it++)
19     {
20         //*it pair
21         cout << it->first <<":" << it->second << endl;
22     }
23     for(const pair<int, string> &p: m) // -std=c++0x(C++11) 注意要用pair
24         cout << p.first << ":" << p.second << endl;
25     return 0;
26 }

b):下标访问

每当用下标访问map元素的时候,如果元素不存在,那么会在map中新生成一个键值对。所以,用下标访问不存在的键值对时,会增加容器的大小。 (应用:单词计数程序)

1     map<string, int> word_count;
2     string word;
3     while (cin >> word) {
4         word_count[word]++;
5     for_each(word_count.begin(), word_count.end(), print);

c):insert操作(map,set有insert操作, 而vector没有)

示例如下;

 1 //本例测试insert的返回值
 2 int main(int argc, const char *argv[])
 3 {
 4     map<string, int> m ;
 5
 6     m.insert(make_pair("hello",1));
 7     m.insert(make_pair("wordl",2));
 8     m.insert(make_pair("foo",1));
 9
10     cout << m.size() << endl; //3
11
12     //insert的返回值类型
13     pair<map<string, int>::iterator, bool> ret ;
14         //插入成功
15     ret = m.insert(make_pair("faasdf",23));
16     cout << "ret:" << ret.second << endl; //1
17         //插入失败
18     ret = m.insert(make_pair("hello",234)); //false
19     cout << "ret:" << ret.second << endl;
20
21     //ret.first 代表指向迭代器的指针。
22     cout << "ret:" << ret.first->second << endl; // 1
23
24     return 0;
25 }

d):count,find 函数测试 key值得存在性。

注意:下标操作 与 count 的区别

使用下标获取value值的时候,存在这样一个弊端,如果下表访问的是不存在的元素,俺么会自动给map 增加一个 key-value键值对,有时候这不是我们所预期的。

而count和find可以较好解决这一问题。

count:仅仅能得出该元素是否存在。

find: 能够返回该元素的迭代器 。

示例代码如下:

 1 //count、 insert、find 测试key存在性
 2 int main(int argc, const char *argv[])
 3 {
 4     map<string, string> m;
 5     m["beijing"] = "good";
 6     m["shanghai"] ="good";
 7     m["shenzhen"]= "good";
 8
 9     cout << m.count("beijing") << endl;// 1
10     cout << m.count("HK") << endl;// 0
11
12     map<string, string>::iterator it = m.find("beijing");
13     //m.find("Hk")--->不存在
14     if(it == m.end())
15         cout << "不存在" <<endl;
16     else
17         cout << it->first <<":" << it->second << endl ; //
18     return 0;
19 }

三:set (停用词功能)

insert、erase、find操作。

实例代码如下:

 1 //set 三个性质; 确定性,唯一性,无序性
 2 //和 map 一样, 采用 红黑树 RB_Tree 有序的  查询时间复杂度 lgN
 3 int main(int argc, const char *argv[])
 4 {
 5     set<int> s ;
 6     int i;
 7     for (i = 0; i < 20; i++)
 8     {
 9         s.insert(i);
10         s.insert(i);
11     }
12     cout << "size:" <<s.size() << endl;// 20 -->唯一性
13
14     for(int i : s) // -std=c++0x
15         cout << i << " " ;
16     cout << endl ;
17     return 0;
18 }

注意:set(集合) 与map(映射) 的区别

a)   二者均使用红黑树实现;

b)   key需要支持<操作(能够比较,对于整个结构体而言,则无法比较);

c)   map侧重于key-value的快速查找;

d)   set侧重于查看元素是否存在。

共同点:map和set中的元素无法排序。由于其具有二叉排序性质,故不能排序。

时间: 2024-10-07 17:07:40

C++学习STL之关联容器 --- pair、map、set的相关文章

C++STL之关联容器【map】【set】

map以键-值対的形式组织,键的作用在于索引,而值表示所存储和读取数据. set仅包含一个键,并且有效的支持某个键是否存在的查询. 他们都是基于标准型类库pair实现,该类型在utility头文件中. 一:关于pair类型的操作 pair<T1,T2> p1; //创建一个空pair类型 pair<T1,T2> p1(v1,v2); //创建并初始化 make_pair(v1,v2) //生成pair对象 <,>,==,!=  //类型之间比较,遵循字典序,先比较fir

初探STL之关联容器

关联容器 分类:set, multiset, map, multimap 特点:内部元素有序排列,新元素插入的位置取决于它的值,查找速度快. 常用函数: find: 查找等于某个值 的元素(x小于y和y小于x同时不成立即为相等) lower_bound : 查找某个下界 upper_bound : 查找某个上界 equal_range : 同时查找上界和下界 count :计算等于某个值的元素个数(x小于y和y小于x同时不成立即为相等) insert: 用以插入一个元素或一个区间 set 特点:

0717-----C++Primer听课笔记----------STL之关联容器

1.Map 1.1 map<K, V>是一种pair的容器,pair的种类是pair<K, V>.map采用下标访问一个已存在的key, 会更新value,访问map中不存在的元素时,会增加一个新的键值对.map中的元素按照key进行从小到大排列.map的底层实现是采用二叉树,一般是使用红黑树. #include <iostream> #include <string> #include <map> using namespace std; /*

STL之关联容器的映射底层

STL的关联容器有set, map, multiset, multimap.用于实现它们的底层容器有划入标准的rb_tree和待加入标准的hashtable. 底层容器rb_tree为上层容器提供了一种有序的服务.关键步骤时间复杂度为O(lgN); 底层容器hashtable为上层容器提供的是无序的服务,但其关键步骤的时间复杂度为O(1). 那么上层容器是怎么映射到底层容器中去的呢?下面以set和map为例,说明它们是如何映射到rb_tree和hashtable的. 1 rb_tree模板头 对

STL之关联容器

关联容器支持高效的关键字查找和访问.两个主要的关联容器(associative-container)类型是map和set.标准库提供8个关联容器,它们的不同体现在三个维度上: 或者是一个set,或者是一个map 或者要求不重复的关键字,或者允许重复关键字 按顺序保存元素,或无序保存. 允许重复关键字的容器的开头名字中都包含单词multi:不保持关键字按顺序存储的容器的名字都以单词unordered开头. 类型map和multimap定义在头文件map中:set和multiset定义在头文件set

Gym - 100989D 题学习stl中的set&lt;pair&lt;int ,int &gt; &gt;

题目网址链接:https://vjudge.net/problem/387095/origin 题目大意:给出桌子数和桌子容纳人数,给出几条操作,操作如下:给出顾客人数,问是否有能容纳顾客且桌子标号和桌子容纳人数与顾客人数差值同时最小的桌子,有即输出桌子编号,没有输出-1:期间会有顾客离开,给出离开的桌子编号. 在做题之前,先学习STL中的set:以集合形式从小到大排列set中的元素. 先给出几个大牛博客链接: https://www.cnblogs.com/zyxStar/p/4542835.

【STL】关联容器 — hash_set

容器hash_set是以hash table为底层机制的,差点儿所有的操作都是转调用hash table提供的接口.因为插入无法存储同样的键值,所以hash_set的插入操作所有都使用hash table的insert_unique接口,代码例如以下: pair<iterator, bool> insert(const value_type& obj) { pair<typename ht::iterator, bool> p = rep.insert_unique(obj

STL - 常用关联容器代码 - set &amp; multiset

代码如下: /* 5. set & multiset */ set<string> cities{ "Braunschweig", "Hanover", "Frankfurt", "New York", "Chicago", "Toronto", "Paris", "Frankfurt" }; multiset<strin

C++ Primer 学习笔记_34_STL实践与分析(8) --引言、pair类型、关联容器

STL实践与分析 --引言.pair类型.关联容器 引言: 关联容器与顺序容器的本质差别在于:关联容器通过键[key]来存储和读取元素,而顺序容器则通过元素在容器中的位置顺序的存取元素. map的元素以键-值[key-value]对的形式组织:键用作元素在map中的索引,而值则表示所存储和读取的数据. set仅包括一个键,并有效的支持关于某个键是否存在的查询. 关联容器类型 map 关联数组:元素通过键来存取 Set 大小可变的集合,支持通过键来实现的高速读取 multimap 支持同一个键多次