c++set和map

目录

一、set的使用

1、set对象的创建

2、multiset

二、map的使用

1、map对象的创建

2、map的operator[]


序列式容器:vector、list、deque....单纯的存储数据,数据和数据之间没有关联
关联式容器:map、set.....不仅仅是存储数据,一般还可以查找数据,数据之间有强关联


一、set的使用

set是默认key模型,但是其实实现的是container,也就是说也可以传入一个pair对象,特别处理
底层结构是红黑树

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

找差集:(同步数据,数据备份,数据修改更新)
思路一:从头开始遍历,双指针,相等都++,不相等,小的就是差集(因为已经不相等了),小的++

set没有实现【】访问

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

其中pair的大小对比关系如下:先比较first,其次是second

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(归并实现

稳定的排序:插入,归并,冒泡(冒泡为数不多的牌面)


 

  • 21
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二十5画生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值