c++ set用法详解
set
set就是集合,STL的set用二叉树实现,集合中的每个元素只出现一次(参照数学中集合的互斥性),并且是排好序的(默认按键值升序排列)
访问元素的时间复杂度是
在c++中,set的头文件是#include<set>
set具有迭代器set<int>::iterator i
定义一个迭代器,名为i 可以把迭代器理解为C语言的指针
set常用操作
set<int> q; //以int型为例 默认按键值升序
set<int,greater<int>> p; //降序排列
int x;
q.insert(x); //将x插入q中
q.erase(x); //删除q中的x元素,返回0或1,0表示set中不存在x
q.clear(); //清空q
q.empty(); //判断q是否为空,若是返回1,否则返回0
q.size(); //返回q中元素的个数
q.find(x); //在q中查找x,返回x的迭代器,若x不存在,则返回指向q尾部的迭代器即 q.end()
q.lower_bound(x); //返回一个迭代器,指向第一个键值不小于x的元素
q.upper_bound(x); //返回一个迭代器,指向第一个键值大于x的元素
q.rend(); //返回第一个元素的的前一个元素迭代器
q.begin(); //返回指向q中第一个元素的迭代器
q.end(); //返回指向q最后一个元素下一个位置的迭代器
q.rbegin(); //返回最后一个元素
set单元素应用
#include<iostream>
#include<set>
using namespace std;
void map_test1()
{
set<int> q; //默认按升序排列
q.insert(5);
q.insert(5);
q.insert(5);
cout << "q.size " << q.size() << endl; //输出 1 ,在set插入中相同元素只会存在一个
q.clear(); //清空set
cout << "q.size " << q.size() << "\n\n";
q.insert(4);
q.insert(4);
q.insert(3);
q.insert(3);
q.insert(2);
q.insert(1);
cout << "lower_bound " << *q.lower_bound(3) << endl; //返回3
cout << "upper_bound " << *q.upper_bound(3) << "\n\n"; //返回4
set<int>::iterator i;
for (i = q.begin(); i != q.end(); i++) //set的遍历
cout << *i << " "; //输出1 2 3 4,可见自动按键值排序
cout << endl;
q.erase(4); //删除q中的 4
for (i = q.begin(); i != q.end(); i++) //再次遍历set 只输出 1 2 3
cout << *i << " ";
cout << "\n\n";
set<int, greater<int>> p; //降序排列
p.insert(1);
p.insert(2);
p.insert(3);
p.insert(4);
p.insert(5);
for (i = p.begin(); i != p.end(); i++)
cout << *i << " ";
cout << endl;
}
int main()
{
map_test1();
return 0;
}
输出结果:
set多元素应用(结构体)
#include<iostream>
#include<set>
using namespace std;
struct node {
int a, b;
bool operator< (const node W)const
{
return a > W.a; //按a的值升序
}
}t;
void map_test2()
{
set<node> q;
t.a = 1;
t.b = 2;
q.insert(t);
t.a = 4;
t.b = 2;
q.insert(t);
t.a = 3;
t.b = 5;
q.insert(t);
set<node>::iterator i;
for (i = q.begin(); i != q.end(); i++)
{
t = *i;
cout << t.a << " " << t.b << endl;
}
}
int main()
{
map_test2();
return 0;
}
输出结果:
map简介
map的功能
自动建立key - value的对应。key 和 value可以是任意你需要的类型,包括自定义类型。
使用map
使用map得包含map类所在的头文件
#include <map> //注意,STL头文件没有扩展名.h
map对象是模板类,需要关键字和存储对象两个模板参数:
std:map<int, string> personnel;
这样就定义了一个用int作为索引,并拥有相关联的指向string的指针.
为了使用方便,可以对模板类进行一下类型定义,
typedef map<int,CString> UDT_MAP_INT_CSTRING;
UDT_MAP_INT_CSTRING enumMap;
map的构造函数
map共提供了6个构造函数,这块涉及到内存分配器这些东西,略过不表,在下面我们将接触到一些map的构造方法,这里要说下的就是,我们通常用如下方法构造一个map:
map的基本操作函数:
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数, (帮助评论区理解: 因为key值不会重复,所以只能是 1 or 0)
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
get_allocator() 返回map的配置器
insert() 插入元素
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
max_size() 返回可以容纳的最大元素个数
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
swap() 交换两个map
upper_bound() 返回键值>给定元素的第一个位置
value_comp() 返回比较元素value的函数
例如:
#include <string>
#include <map>
void TestMap()
{
map<string, string> m;
// 向map中插入元素的方式:
// 将键值对<"peach","桃子">插入map中,用pair直接来构造键值对
m.insert(pair<string, string>("peach", "桃子"));
// 将键值对<"peach","桃子">插入map中,用make_pair函数来构造键值对
m.insert(make_pair("banan", "香蕉"));
// 借用operator[]向map中插入元素
/*
operator[]的原理是:
用<key, T()>构造一个键值对,然后调用insert()函数将该键值对插入到map中
如果key已经存在,插入失败,insert函数返回该key所在位置的迭代器
如果key不存在,插入成功,insert函数返回新插入元素所在位置的迭代器
operator[]函数最后将insert返回值键值对中的value返回
*/
// 将<"apple", "">插入map中,插入成功,返回value的引用,将“苹果”赋值给该引
用结果,
m["apple"] = "苹果";
// key不存在时抛异常
//m.at("waterme") = "水蜜桃";
cout << m.size() << endl;
// 用迭代器去遍历map中的元素,可以得到一个按照key排序的序列
for (auto& e : m)
cout << e.first << "--->" << e.second << endl;
cout << endl;
// map中的键值对key一定是唯一的,如果key存在将插入失败
auto ret = m.insert(make_pair("peach", "桃色"));
if (ret.second)
cout << "<peach, 桃色>不在map中, 已经插入" << endl;
else
cout << "键值为peach的元素已经存在:" << ret.first->first << "--->"
<< ret.first->second <<" 插入失败"<< endl;
// 删除key为"apple"的元素
m.erase("apple");
if (1 == m.count("apple"))
cout << "apple还在" << endl;
else
cout << "apple被吃了" << endl;
}
multiset
multiset的介绍
multiset的使用
#include <set>
void TestSet()
{
int array[] = { 2, 1, 3, 9, 6, 0, 5, 8, 4, 7 };
// 注意:multiset在底层实际存储的是<int, int>的键值对
multiset<int> s(array, array + sizeof(array)/sizeof(array[0]));
for (auto& e : s)
cout << e << " ";
cout << endl;
return 0;
}
multimap
multimap的介绍
multimap的使用
底层结构