【C++ STL】初始map、set


前言

map 和 set 是 STL 中的关联式容器,底层是平衡二叉搜索树,map( key 模型),set( key,val 模型)。

一、set

1.insert

关于 set 的 insert 函数,使用起来也很简单,首先是 set 所要包含的头文件:

#include<set>

其次就是函数的调用了,根据模板参数传递参数,比如:

set<int> s;
s.insert(2);
s.insert(2);
s.insert(1);
s.insert(5);
s.insert(3);

输出的话,使用范围for或者迭代器遍历都行,如下:

int main()
{
	set<int> s;
	s.insert(2);
	s.insert(2);
	s.insert(1);
	s.insert(5);
	s.insert(3);

	set<int>::iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	return 0;
}

在这里插入图片描述
可以看到输出结果是这样的,因为set的底层是平衡二叉搜索树,所以是不允许重复的 key 存在的,所以可以理解为set 会做数据的去重操作,而 set 对于数据默认是做升序处理。

那么 set 是否可以修改数据呢?来进行如下尝试:

int main()
{
	set<int> s;
	s.insert(2);
	s.insert(2);
	s.insert(1);
	s.insert(5);
	s.insert(3);

	set<int>::iterator it = s.begin();
	while (it != s.end())
	{
		*it += 1; //key += 1
		cout << *it << " ";
		++it;
	}
	cout << endl;

	return 0;
}

在这里插入图片描述
答案是不行的,因为底层是平衡二叉搜索树,如果要修改某一个key时,就有可能会破坏原来搜索的规则,我们知道二叉搜索树 root 的 key 比左子树的大,比右子树的小,当我们要修改一个节点的 key 时,可能导致不满足这个规则,所以 set 是不允许修改key的值的。

2.count

set 的 count 函数就是在容器中搜索与传入的参数等效的元素,并返回匹配的数量,而因为 set 中的所有元素都是唯一的,所以函数只能返回 1(如果找到元素)或 0(否则)。

比如:

int main()
{
	set<int> s;
	s.insert(2);
	s.insert(2);
	s.insert(1);
	s.insert(5);
	s.insert(3);

	//set {1,2,3,5}
	//找1
	cout << s.count(1) << endl;

	//找10
	cout << s.count(10) << endl;

	return 0;
}

在这里插入图片描述
结果显而易见。

二、multiset

1.insert

multiset 的 insert 和 set 的唯一区别就是它的 insert 不去重,即允许重复的 key 存在,比如:

int main()
{
	multiset<int> s;
	s.insert(2);
	s.insert(2);
	s.insert(1);
	s.insert(5);
	s.insert(3);

	multiset<int>::iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	return 0;
}

在这里插入图片描述
其他的没有区别,一样是不允许修改 key 的值。

2.find

find 函数会返回查找到的 key 的迭代器,因为 multiset 允许存在重复的 key,所以在调用 find 函数时会返回中序的第一个 key 的迭代器,比如:
在这里插入图片描述
即在 find(1) 时,会返回多个 1 中的中序的第一个 1。

3.count

multiset 的 count 返回的是 key 出现的次数,即:

int main()
{
	multiset<int> s;
	s.insert(2);
	s.insert(2);
	s.insert(1);
	s.insert(5);
	s.insert(3);

	cout << s.count(2) << endl;;
	cout << s.count(5) << endl;
	return 0;
}

在这里插入图片描述
因为允许重复的 key 存在,所以这样的结果也是理所当然。

三、map

1.insert

map 的值存的是键值对,即<key,val>,所以不能像set直接插入,要借助类 pair<const key_type,mapped_type>,
pair中存在两个成员变量,一个是 first,即 key,一个是 second,即 val。

使用匿名对象 pair 进行插入:

map<string, int> countMap;
countMap.insert(pair<string,int>("苹果",1));

使用 make_pair 进行插入:
make_pair 是一个函数模板,通过其可以构造出一个 pair,而使用 make_pair 的好处就是不需要像使用 pair 那样显示的传递参数的类型,可以直接传递参数而自动进行类型的推导:

map<string, int> countMap;
countMap.insert(make_pair("苹果",1));

map 中依然是不允许有重复的key存在的。

2.operator[ ]

map 的方括号重载是很有用的,对于统计某个 key 出现的次数是很好用的,operator[ ] 大致的执行流程是,通过参数传递一个 key ,最终会返回该 key 的键值对对应的 val 的引用,而 val 如果不赋值,默认会调用其默认构造,可以通过赋值来改变相应 key 的 val 值,做到对同一个 key 的统计,比如:

int main()
{
	string str[] = { "apple","apple","banana","pear","pear" };
	map<string, int> countMap;
	for (const auto& e : str)
	{
		countMap[e]++;
	}
	
	for (const auto& e : countMap)
	{
		cout << e.first << ": " << e.second << endl;
	}
	return 0;
}

在这里插入图片描述

四、multimap

和 map 没有太大的区别,也就是支持重复的 key 存在,比如:

int main()
{
	multimap<string, string> mmap;
	mmap.insert(make_pair("string","字符串1"));
	mmap.insert(make_pair("string","字符串2"));
	auto it = mmap.begin();
	cout << it->first << ": " << it->second << endl;
	++it;
	cout << it->first << ": " << it->second << endl;
	return 0;
}

在这里插入图片描述

总结

温故而知新。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值