map
map的操作参考文章《C++ Primer 学习笔记_35_STL实践与分析(9)--map类型(上) 》《C++ Primer 学习笔记_36_STL实践与分析(10)--map类型(下) 》
map的特性:所有元素会按照元素的键值自动排序。map所有元素都是pair,第一个元素视为键值,第二个元素视为实值;map不允许两个元素拥有相同的键值。
可以修改元素的实值,但是不能修改元素的键值(键值是const类型的),因此map的迭代器既不是constant Iterators,也不是mutale Iterators。
set
set的操作参考文章《C++ Primer 学习笔记_37_STL实践与分析(11)--set类型》
set是STL中的标准容器,set里面的元素会根据键值自动排序,它不像map那样拥有实值value和键值key的对应,set只有实值。SET的底层实现是RB-tree,当插入到RB-tree中后,其值不能再更改,因为更改就意味着可能不符合RB-tree的特性了,所以其迭代器set<T>::iterator是RB-tree的constrant iterator。由于set底层是RB-tree,所以set在插入等操作之后,迭代器不会失效,但删除元素的迭代器是个例外。
当只想知道一个值是否存在时,使用set容器最合适。因为set是自动排序的,不会存在相同的元素,因此可以很轻易判断某个元素是否存在于set中。例如可以轻松找到某个人名是否存在于列表:
string name;
set<string> sset;
cin >> name;
if (set.count(name))
cout << "找到了" << endl;
上述代码输入一个name,通过set的count函数判断name是否存在于set中。若存在count返回1,否则返回0.
map与vector的区别:
(1) 用下标访问map中并不存在的元素会导致在map容器中添加该元素,该元素键即为该下标值。能作为map下标的类型必须是定义了“小于”操作符的类型,因为键值在标准库中默认是通过小于操作比较的。
(2)当对元素进行插入或删除操作时,操作之前的所有迭代器,在操作完成后依然有效;当然被删除那个元素的迭代器是例外。(set与map类似)。这是由于其内部结构决定的。map和set的底层容器是RB-tree,是指针之间连接元素的,因此插入删除不会导致迭代器失效。
但是vector(包括deque)的插入或删除操作却可能是部分或全部迭代器失效。这同样是由其底层实现机制决定的,因为vector和list插入或删除都会重新分配空间,这样迭代器肯定会失效。关于vector以及deque的空间分配方法参考文章《STL源码:vector》《STL源码:deque》。
map与set的区别以及适用范围
相同点:都存储键值。
都要保证键值的唯一性,而且不能修改。
都支持构造函数、insert、erase和count、find等操作。
不同点:set支持map的大部分操作,但是set不支持下标访问,也没有定义mapped_type类型。
set纯粹是键的集合,而map是pair的集合。
map适合用于需要了解键值与值之间对应关系的情况,例如,字典,要了解单词(键)与其解释(值)之间对应关系的情况;set适用于仅需判断某值是否存在的情况,例如判断某人姓名是否在名单中。
set与list的区别
一个相同点:当对元素进行插入或删除操作时,操作之前的所有迭代器,在操作完成后依然有效;当然被删除那个元素的迭代器是例外。(map和set类似)
主要差别:set的元素不能修改,list无此限制。
set适用于保存元素值不变的集合,list适用于保存会发生变化的元素。