当前位置:网站首页>set和map使用讲解

set和map使用讲解

2022-08-10 17:56:00 '派派'

目录

1.set

1.1介绍set - C++ Reference

1.2set的使用

1. set的模板参数列表

 2.set构造

 3.常用接口

1.3multiset

2.map  

2.1关联式容器,键值对

2.2map的介绍 map - C++ Reference

2.3map的常用接口 

1.insert

2. operator[]

3.erase等

4.multipmap


1.set

1.1介绍set - C++ Reference

1.set是按照一定次序存储元素的容器。
2.set在底层是用二叉搜索树(红黑树)实现的。
3. set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。
set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。
注意:
1. 与map/multimap不同,map/multimap中存储的是真正的键值对<key, value>,set中只放
value,但在底层实际存放的是由<value, value>构成的键值对,插入元素时,只需要插入value即可。
2.set中的元素不可以重复,元素默认按照小于来比较 ,使用set的迭代器遍历set中的元素,可以得到有序队列。

1.2set的使用

1. set的模板参数列表

 2.set构造

3.常用接口

 直接查找某个值

支持插入一段区间,一个值,具体某个位置上插入(很少用)

 删除一段区间,某个位置上的值,一个值 

返回元素个数

void test1() 
{
	set<int> s;
	s.insert(3);
	s.insert(8);
	s.insert(2);
	s.insert(1);
	s.insert(1);
	s.insert(6);
	s.insert(9);
	s.insert(1);
	s.insert(9);
	set<int>::iterator it = s.begin();
	while (it != s.end())//进行排序,去重
	{
		cout << *it << " ";
		it++;
	}
}
  set<int>::iterator pos = s.find(4);
	if (pos != s.end())
	{
		cout << "set.find找到了" << endl;
	}
	else
	{
		cout << "未找到" << endl;
	}

	cout << s.erase(3) << endl;//删除返回元素的个数
	cout << s.erase(20) << endl;//失败返回0
	pos = s.find(100);
	//s.erase(pos);      //这样删除不存在的数会报错
	if (pos != s.end())
	{
		s.erase(pos);
	}
    if (s.count(6))//可用来判断元素是否纯在
	{
		cout << "6存在" << endl;
	}

结果:

lower_bound:返回大于等于val的值

upper_bound:返回大于val的值

 例如:

void test2()
{
	set<int> s;
	s.insert(2);
	s.insert(4);
	s.insert(1);
	s.insert(6);
	for (auto& ch : s)
	{
		cout << ch << " ";
	}
	cout << endl;
	set<int>::iterator lowit = s.lower_bound(2);//返回>=2位置的迭代器
	set<int>::iterator upit = s.upper_bound(5);//返回>5位置的迭代器
	s.erase(lowit, upit);//左闭右开。刚好把[2-5]间的值删除
	for (auto& ch : s)
	{
		cout << ch << " ";
	}
	cout << endl;
}

 结果:

 

1.3multiset

 介绍:与set类似,但可存储相同值的元素

void test3()
{
	multiset<int> s;
	s.insert(2);
	s.insert(4);
	s.insert(3);
	s.insert(8);
	s.insert(8);
	s.insert(8);
	s.insert(12);
	s.insert(3);
	s.insert(7);
	s.insert(5);
	for (auto& ch : s)
	{
		cout << ch << " ";
	}
	cout << endl;
	cout << s.erase(8) << endl;//会把8全部删除,返回删除的元素个数
	cout <<"3的个数:" << s.count(3) << endl;//返回查找的元素个数
	for (auto& ch : s)
	{
		cout << ch << " ";
	}
}

结果:

2.map  

2.1关联式容器,键值对

介绍:

STL中的部分容器,比如:vector、list、deque、forward_list(C++11)等,
这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面存储的是元素本身。

关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是<key, value>结构的
键值对,在数据检索时比序列式容器效率更高。
键值对:用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代
表键值,value表示与key对应的信息

2.2map的介绍 map - C++ Reference

1. map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元
素。
2. map中,键值key通常用于排序和唯一地标识元素,而值value中存储与此键值key关联的
内容。键值key和值value的类型可能不同,并且在map的内部,keyvalue通过成员类型
value_type绑定在一起,为其取别名称为pair。
3. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))
4.map中的key是唯一的,并且不能被修改。
5. 支持[]操作符,operator[]中实际进行插入查找。

key: 键值对中key的类型
T: 键值对中value的类型
Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比
较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户
自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)
Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的
空间配置器

2.3map的常用接口 

大部分与set是类似的,不过多介绍。

1.insert

 make_pair是一个函数模板

 举例:

void test3()
{
	map<string, string> m;
	m.insert(pair<string, string>("sort", "排序"));
	pair<string, string> kv("insert", "插入");
	m.insert(kv);
	m.insert(make_pair("left", "左边"));
	m.insert(make_pair("English", "英语"));
	map<string, string>::iterator it = m.begin();
	while (it != m.end())
	{
		cout << it->first << "-" << it->second << " ";
		++it;
	}
	cout << endl;
	for (auto& ch : m)
	{
		cout << ch.first << "-" << ch.second << " ";
	}
	cout << endl;
}

结果:按key类型进行排序

 insert的返回值:是一个pair<iterator,bool>,插入成功,iterator是指向新插入元素的迭代器,bool为true;插入失败,iterator是当前元素的的迭代器,bool为false

 例如:

void test4()
{
	string arr[] = { "苹果", "西红柿", "苹果", "桃", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
	map<string, int> countMap1;
	for (auto& str : arr)//统计水果的个数
	{
		map<string, int>::iterator it = countMap1.find(str);
		if (it != countMap1.end())
		{
			it->second++;
		}
		else
		{
			countMap1.insert(make_pair(str, 1));
		}
	}
	map<string, int> countMap2;
	for (auto& str : arr)
	{
		pair<map<string, int>::iterator, bool> ret = countMap2.insert(make_pair(str, 1));
		if (ret.second == false)
		{
			ret.first->second++;
		}
	}
	for (auto& ch : countMap1)
	{
		cout << ch.first << "-" << ch.second << " ";
	}
	cout << endl;

	for (auto& ch : countMap2)
	{
		cout << ch.first << "-" << ch.second << " ";
	}
	cout << endl;
}

结果:

2. operator[]

 源码实现类似于:

mapped_type& operator[] (const key_type& k)
{
	pair<iterator,bool> ret = insert(make_pair(k, mapped_type()));

	//return (*(ret.first)).second;
	return ret.first->second;//返回的是第二个参数的引用,可以修改
}

 mapped_type是第二个参数的类型,上面是构造的匿名对象。

可充当查找,修改,插入的功能

如果插入数据成功(返回的是插入新元素的第二个参数的引用),如果数据存在,返回的是该数据的第二个参数的引用,也可以把它修改。

举例:

void test5()
{
	string arr[] = { "苹果", "西红柿", "苹果", "桃", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
	map<string, int> countMap;
	for (auto& str : arr)
	{
		countMap[str]++;
	}
	for (auto& ch : countMap)
	{
		cout << ch.first << "-" << ch.second << " ";
	}
	cout << endl;
	map<string, string> m;
	m.insert(make_pair("suffer", "痛苦"));
	m.insert(make_pair("extend", "扩大"));
	m.insert(make_pair("left", "左边"));
	m["suffer"] = "遭受";//查找+修改
	m["right"] = "右边";//插入新数据
	for (auto& ch : m)
	{
		cout << ch.first << "-" << ch.second << " ";
	}
	cout << m["extend"] << endl;//查找该数据
}

 结果:

 3.erase等

void test6()
{
	string arr[] = { "苹果", "西红柿", "苹果", "桃", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
	map<string, int> m;
	for (auto& str : arr)
	{
	  m[str]++;
	}
	m.erase("苹果");
	for (auto& ch : m)
	{
		cout << ch.first << "-" << ch.second << " ";
	}
}

结果:
桃-1 西瓜-1 西红柿-1 香蕉-2

其余接口与set也是类似的,这里不再叙述

4.multipmap

介绍:支持插入相同元素,其余与map是类似的,但不支持[].

原网站

版权声明
本文为['派派']所创,转载请带上原文链接,感谢
https://blog.csdn.net/m0_64397669/article/details/126235802