目录
一、set的使用
1、set对象的创建
2、multiset
二、map的使用
1、map对象的创建
2、map的operator[]
序列式容器:vector、list、deque....单纯的存储数据,数据和数据之间没有关联
关联式容器:map、set.....不仅仅是存储数据,一般还可以查找数据,数据之间有强关联
一、set的使用
set是key模型
底层结构是红黑树
1、set对象的创建
set<int> s;
s.insert(1);
s.insert(1);
s.insert(99);
s.insert(29);
s.insert(290);
for (auto e : s)
{
cout << e << " ";
}
cout << endl;
set - C++ Reference (cplusplus.com)这实在没什么讲的,直接看文档吧。
lower_bound >=
uper_bound < #返回下一个值
因为删除是左闭右开,迭代器规定必须是左闭右开
做题找交集:(可以做查重)
思路一:从头开始遍历,双指针,相等都++,不相等,小的++
思路二:两个都交给set,然后其中一个到另外一个内部遍历,结束位置,找到了就插入新的vector
找差集:(同步数据,数据备份,数据修改更新)
思路一:从头开始遍历,双指针,相等都++,不相等,小的就是差集(因为已经不相等了),小的++
2、multiset
multiset - C++ Reference (cplusplus.com)
multi多样的
允许冗余,不去重
在multiset中,相等值可以在左边,也可以在右边,看具体实现逻辑
数据冗余,find的是中序的第一个
为什么是找到中序的第一个?
因为对搜索树来说,中序返回序列就是排序
返回第一个中序的位置,就可以对相同数据进行访问
二、map的使用
map是一个k-val模型(关联式容器)
1、map对象的创建
map<const Key,Value>
创建对象:用pair<key,value>创建对象
map的每一个节点,都是一个pair
map - C++ Reference (cplusplus.com)#文档
multimap - C++ Reference (cplusplus.com)
//创建以及插入方式一(普通对象)
map<string, string> dict;
pair<string, string> k_val1 = { "A","a" };
dict.insert(k_val1);
//创建以及插入方式二(innither_list)
dict = { { "B","b"}, {"C","c"}, {"D","d"} };
//创建以及插入方式三(匿名对象)
dict.insert(pair<string, string> {"F", "f"});
//创建以及插入方式三(隐式类型转换)
dict.insert({"I", "i"});
for (auto& e : dict)
{
cout << e.first << ":" << e.second <<endl;
}
单参数构造函数支持隐式类型转换
单参数构造函数也支持隐式类型转换,使用{}花括号实现
这里的是转化为pair对象
因为pair内有多参数构造函数
临时变量具有常性
隐式类型转换中间会产生一个临时变量
pair不支持流插入
需要key和value分别打印
第一个叫first,第二个叫second
范围for最好把引用用上,因为是iterator指针深拷贝给auto,代价太大
同时,如果不修改,就使用const
key不能修改,但是second可以
因为搜索树是根据key构成搜索树的
list的迭代器内部封装一个node指针
map和set也是封装一个树节点指针
2、map的operator[]
下标访问的值是key
不管key在不在,返回的都是key所在节点的迭代器的value的引用
即,返回value的引用
两种可能:
一种是key原来就有,插入失败,返回原来key的节点指针
一种是key原来没有,插入成功,返回当前新插入的节点指针
底层是:
pair<itertor,bool> ret = insert(make_pair(key,v()))
return (ret.first)->second;#返回值的pair的第一个值是key位置的迭代器,第二个位置是是否插入成功判断
所以,
1、【】可以是插入的功能,此时value相当于一个缺省值
2、也可以是插入+修改:dict[key] = new_value(因为返回的是value的引用)
3、还可以查找,返回值的pair的secondhi一个bool值,原来的key存在返回true
如果已经存在,不会插入,返回的是当前key节点的value的引用
4、也可以修改(已知存在的情况下用,否则就会插入)
5、对value进行统计
怎么做到的?主要是pair的value构造是一个缺省值,返回值是value的引用,可以直接进行修改++
一下是一个简单的实例:
void test_map1()
{
map<string, int> m;
m["A"];//插入
m["B"]++;//修改value+1
m["C"];//
m["D"];
//auto打印
for (auto& e : m)
{
cout << e.first << ":" << e.second << endl;
}
//迭代器打印
//map<string, int>::iterator it = m.begin();
//while (it != m.end())
//{
// cout << it->first << ":" << it->second << endl;
// //cout << it.operator->()->first << ":" << it.operator->()->second << endl;
// ++it;
//}
//查找
if (m["D"])
{
cout << "D存在" << endl;
}
else
{
cout << "D不存在" << endl;
}
if (m["W"])
{
cout << "W存在" << endl;
}
else
{
cout << "W不存在" << endl;
}
}
count返回个数
mutilmap允许冗余
稳定排序:stable_sort(归并实现
稳定的排序:插入,归并,冒泡(冒泡为数不多的牌面)