C++ set和map使用

set和map

  • 1.关联式容器
  • [2. 键值对](#2. 键值对)
  • [3. set](#3. set)
    • [3.1 介绍](#3.1 介绍)
    • [3.2 简单使用](#3.2 简单使用)
  • 4.multiset
  • 5.map
    • [5.1 介绍](#5.1 介绍)
    • [5.2 简单使用](#5.2 简单使用)
  • [6. multimap](#6. multimap)

1.关联式容器

关联式容器是一种STL容器,用于存储键-值对。它们提供了一种通过键来快速查找值的机制。STL总共实现了两种不同结构的管理式容器:树型结构(map、set、multimap、multiset)与哈希结构 。在关联式容器中,里面存储的是<key, value>结构的键值对,在数据检索时比序列式容器效率更高.

2. 键值对

概念:用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。

STL中键值对结构的定义:

cpp 复制代码
template<class T1,class T2>
struct pair
{
	typedef T1 first_type; 
	typedef T2 second_type;
	
	T1 first;
	T2 second;
	pair():first(T1()),second(T2())
	{}
	pair(const T1& a,const T2& b):first(a),second(b)
	{}
};

3. set

3.1 介绍

  1. set的底层是二叉搜索树(红黑树)。
  2. set中的数据是有序去重的。
  3. set中的数据是被const 修饰的,所以不能修改,但是可以插入和删除。
  4. set默认的排序是按照从小到大的。如果想要按照自己的想法排序,需要自己写一个仿函数。
  5. 和map不同的是,set底层的键值对不是<key,value>而是<value,value>。
  6. set容器查找效率很高,时间复杂度为O(log2 N)

3.2 简单使用

  1. begin()    返回set容器的第一个元素
  2. end()      返回set容器的最后一个元素
  3. clear()    删除set容器中的所有的元素
  4. empty()    判断set容器是否为空
  5. insert()    插入一个元素
  6. size()      set容器内元素个数
  7. clear()    清空容器
cpp 复制代码
int main()
{
	//去重加排序
	set<int> s;
	s.insert(10);
	s.insert(10);
	s.insert(1);
	s.insert(20);
	s.insert(20);
	s.insert(8);
	s.insert(5);
	cout << s.size() << endl;
	set<int>::iterator it = s.begin();
	while (it != s.end())
		cout << *it++ << " ";
	cout << endl;
	s.clear();
	cout << s.size();
	return 0;
}
  1. count()
    用来查找set中某个某个键值出现的次数。这个函数在set并不是很实用,因为一个键值在set只可能出现0或1次,这样就变成了判断某一键值是否在set出现过了
cpp 复制代码
void test2()
{
	set<int> s;
	s.insert(10);
	s.insert(10);
	s.insert(1);
	s.insert(20);
	s.insert(20);
	s.insert(8);
	s.insert(5);
	cout << "10的个数:" << s.count(10) << endl;
	cout << "5的个数:" << s.count(5) << endl;
	cout << "100的个数:" << s.count(100) << endl;
	if (s.count(10))
	{
		//do...
	}
}

erase(iterator)       删除迭代器iterator指向的值

erase(first,second)       删除迭代器first和second之间的值

erase(key_value)       删除键值key_value的值
注:前两个必须保证迭代器有效,不然程序会崩溃,最后一个,不管值存不存在都可以

cpp 复制代码
void test3()
{
	set<int> s;
	set<int>::const_iterator iter;
	set<int>::iterator first;
	set<int>::iterator second;
	for (int i = 1; i <= 10; ++i)
		{
		    s.insert(i);
		}
	//第一种删除
		s.erase(s.begin());
	//第二种删除
	first = s.begin();
	second = s.begin();
	second++;
	second++;
	s.erase(first, second);
	//第三种删除
		s.erase(8);
	cout << "删除后 set 中元素是 :";
	for (iter = s.begin(); iter != s.end(); ++iter)
	{
		cout << *iter << " ";
	}
	cout << endl;
	
}

lower_bound(key_value)       返回第一个大于等于key_value的迭代器

upper_bound(key_value)      返回最后一个大于key_value的迭代器

这两个函数也可以用于于删除一个区间的数据。

cpp 复制代码
void test4()
{
	set<int> s;
	s.insert(5);
	s.insert(1);
	s.insert(6);
	s.insert(3);
	s.insert(4);

	auto start = s.lower_bound(3);  // >=val
	cout << *start << endl;

	auto finish = s.upper_bound(5);  // >val
	cout << *finish << endl;
	

	while (start != finish)
	{
		cout << *start << " ";
		++start;
	}
	cout << endl;
}

4.multiset

该容器允许键值重复,其他的使用和set差不多。这样count()的作用就显现出来了。还有一个不同的是find()返回的是中序遍历的第一个。

5.map

5.1 介绍

  1. map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元 素。
  2. 在map中,键值key通常用于排序和唯一的标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,为其取别名称为pair: typedef pair<const key, T> value_type;
  3. 在内部,map中的元素总是按照键值key进行比较排序(默认升序)的。
  4. 和set一样key不允许修改,但是key所关联的value可以修改。
  5. map支持下标访问符(set不支持),即在[]中放入key,就可以找到与key对应的value。
  6. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))

5.2 简单使用

map的使用和set的使用基本是差不多,但是map的[]运算符使用起来还是很方便的,下面就简单介绍几种。

  1. 插入数据的几种方法:
cpp 复制代码
//1.直接insert pair
map<string,int> m;
m.insert(pair<string,int>("apple",1));
cpp 复制代码
//2. 直接insert value_type 其实本质和第一种方式一样
map<string,int> m;
m.insert(map<string,int>::value_type("apple",1));
cpp 复制代码
//3. 使用[]运算符,这种是最简便的方法
map<string,int> m;
m["apple"] = 1;
  1. 修改数据
cpp 复制代码
//如果数据原本不存在,就相当于插入操作
map<string,int> m;
m["apple"]++;
  1. 查找数据
cpp 复制代码
map<string,int> m;
if(m["apple"])
cout << m[apple] << endl;

6. multimap

和map不同的是,multimap允许有重复的key值,但这同时也导致了multimap没有[]这个运算符,因为会导致二义性。

相关推荐
Fcy6482 分钟前
C++ set&&map的模拟实现
开发语言·c++·stl
李慕婉学姐6 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
fpcc7 小时前
C++编程实践——链式调用的实践
c++
奋进的芋圆8 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin8 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model20058 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉9 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国9 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_941882489 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
bkspiderx9 小时前
C++中的volatile:从原理到实践的全面解析
开发语言·c++·volatile