set和map属于关联容器。其他多属于顺序容器。关联容器和顺序容器有着根本的不同:关联容器中的元素是按关键字来保存和访问的。与之相对,顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的。
在不用到set/map的排序时,建议使用unordered_set/unordered_map(C++11),其速度要比set/map快的多
map
下面是对文章中介绍map用法的一些照搬
map的使用
1
2
std::map<int, string> mapStudent;访问map中的元素
可以直接通过
m[key]
进行访问map插入一个元素
1
2
3
4
5
6// 最简单的一种
mapStudent.insert({1, "student_first"});
// 1. 插入,用insert函数插入pair数据
mapStudent.insert(pair<int, string>(1, "student_one"));
// 2. 用insert函数插入value_type数据
mapStudent.insert(map<int, string>::value_type (2, "student_two"));当map中有这个关键字时,insert操作是插入不了的,但是用数组方式就不同了,它可以覆盖以前该关键字对应的值
检验插入是否成功
1
2
3
4
5
6
7pair<map<int, string>::iterator, bool> Insert_Pair;
Insert_Pair = mapStudent.insert(pair<int, string>(1, "student_one"));
if(Insert_Pair.second == true)
cout<<"Insert Successfully"<<endl;
else
cout<<"Insert Failure"<<endl;map更改元素的值
1
2// 通过数组形式更新元素
mapStudent[3] = "student_three";map遍历所有的元素
1
2
3for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
cout<<iter->first<<' '<<iter->second<<endl;
// 判断map的大小,也可以使用 mapStudent.size()查找并获取map中的元素
使用find()函数,传入要查找的key
1
2
3
4
5
6map<int, int> m;
m.insert({1, 23});
map<int, int>::iterator iter;
iter = m.find(1);
if(iter != m.end())
cout<<"find the item whose key is 1\n";find_if()的使用
1
2
3
4
5
6template<class InputIterator, class Predicate>
InputIterator find_if ( InputIterator first, InputIterator last, Predicate pred )
{
for ( ; first!=last ; first++ ) if ( pred(*first) ) break;
return first;
}它在区间[first,end)中搜寻使一元判断式pred为true的第一个元素。
如果没找到,返回end
我们只需要填入参数,这是一个封装好的函数
pred函数要有返回值
从map中删除数据
1
2
3
4
5
6
7
8iterator erase(iterator it);//通过一个条目对象删除
iterator erase(iterator first,iterator last)//删除一个范围
size_type erase(const Key&key);//通过关键字删除
int n = mapStudent.erase(1);//如果删除了会返回1,否则返回0
clear()就相当于enumMap.erase(enumMap.begin(),enumMap.end());map中的swap用法
map中的swap不是一个容器中的元素交换,而是两个容器所有元素的交换。
排序 · map中的sort问题
map中的元素是自动按Key升序排序,所以不能对map用sort函数
这里要讲的是一点比较高深的用法了,排序问题,STL中默认是采用小于号来排序的,以上代码在排序上是不存在任何问题的,因为上面的关键字是int 型,它本身支持小于号运算,在一些特殊情况,比如关键字是一个结构体,涉及到排序就会出现问题,因为它没有小于号操作,insert等函数在编译的时候过 不去,下面给出两个方法解决这个问题。
set
set是一个容量动态变化的容器(使用了红黑树)【只能通过遍历访问子元素,不能通过索引,但可以使用find】,且系统会为其储存元素按递增排序;
- 如果存入自定义结构,可以重写
<、>
操作符 - 常见操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20begin(); // 返回指向第一个元素的迭代器
end(); // 返回指向最后一个元素的迭代器
clear(); // 清除所有元素
count(); // 返回某个值元素的个数
empty(); // 如果集合为空,返回true
equal_range(); // 返回集合中与给定值相等的上下限的两个迭代器
erase() // 删除集合中的元素
find() // 返回一个指向被查找到元素的迭代器
get_allocator() // 返回集合的分配器
insert() // 在集合中插入元素
// set中进行插入的insert函数。其实这个函数是有返回值的,只不过我们不常用。它的返回值是一个pair,first成员就是指向新插入的元素在set中位置的迭代器,second成员是一个bool表示这次插入操作是否成功。
lower_bound() // 返回指向大于(或等于)某值的第一个元素的迭代器
key_comp() // 返回一个用于元素间值比较的函数
max_size() // 返回集合能容纳的元素的最大限值
rbegin() // 返回指向集合中最后一个元素的反向迭代器
rend() // 返回指向集合中第一个元素的反向迭代器
size() // 集合中元素的数目
swap() // 交换两个集合变量
upper_bound() // 返回大于某个值元素的迭代器
value_comp() // 返回一个用于比较元素间的值的函数