C++ pair的用法

C++ pair的用法

1.pair是什么
2.基本语法
3.排序时的工作原理
4.pair和结构体的区别
5.pair的例题

1.pair是什么

pair<T1,T2>是C++标准模板库中的一个模板类,用于将两个不同类型的值组合成一个单一对象。
其中:
T1和T2是模板参数,可以是任意数据类型。

2.基本语法:

#include <utility>  // pair的定义在utility头文件中

pair<int, int> p;            // 创建一个pair
p.first = 10;               // 访问第一个元素
p.second = 20;              // 访问第二个元素

pair<int, int> p2(5, 6);     // 直接初始化
pair<int, int> p3 = {1, 2};  // C++11起支持的列表初始化

可以将pair与其他容器结合使用,创建复杂的数据结构。例如,使用vector存储pair:

vector<pair<int, int>> v(n);
// 创建一个存储n个pair的vector,每个pair表示一个区间[l, r]

v[i].first   // 第i个区间的左端点l
v[i].second  // 第i个区间的右端点r

3.排序时的工作原理

sort(v.begin(),v.end());

//先比较first(左端点),如果相等再比较second(右端点)

性能考虑和最佳实践
pair的性能取决于其成员类型的性能。对于小型数据类型,pair通常非常高效。对于大型对象,考虑使用引用或指针。
pair模板是许多STL实现的基础,比如map容器实际上就是存储了pair<const Key, Value>元素的集合。它的简洁设计使得处理成对数据变得非常高效和方便。

4.pair和结构体的区别

 pair是标准模板库(STL)中的模板类,通常用于存储【两个】不同类型的元素。pair严格限定为两个成员(first和second),无法扩展。
 
 结构体是用户自定义的数据类型,可以包含【多个】不同类型的成员变量,灵活性更高。

5.pair例题-区间合并问题

在这里插入图片描述
在这里插入图片描述

区间合并问题,我们可以用贪心算法解决。思路如下:

1.将所有区间按左端点从小到大排序

2.维护当前合并区间的左右端点

3.遍历排序后的区间:

4.如果当前区间与合并区间有交集(当前区间的左端点 ≤ 合并区间的右端点),则更新合并区间的右端点

  否则,将合并区间计数,并开始一个新的合并区间

代码如下:

#include <bits/stdc++.h>
using namespace std;

int main() {
	int n;
	cin>>n;
	vector<pair<int,int>> v(n);  // 创建一个大小为n的vector,存储所有区间
	
	// 读入n个区间
	for(int i=0; i<n; i++) {
		cin>>v[i].first>>v[i].second;  // first存储左端点,second存储右端点
	}
	
	// 关键步骤1:按左端点从小到大排序
	sort(v.begin(),v.end());  // pair默认先按first排序,再按second排序
	
	// 初始化:第一个区间作为当前合并区间
	int cnt=1;  // 合并后的区间个数,初始化为1(第一个区间)
	int left=v[0].first;   // 当前合并区间的左端点
	int right=v[0].second; // 当前合并区间的右端点
	
	// 关键步骤2:线性扫描所有区间
	for(int i=1; i<n; i++) {
		// 如果当前区间与合并区间有交集(端点相交也算)
		if(v[i].first<=right) {
			// 合并区间:更新合并区间的右端点
			// 取max是为了处理包含关系,确保右端点最大
			right=max(right,v[i].second);
		}
		else {
			// 无交集,当前合并区间结束,开始新的合并区间
			cnt++;  // 区间个数加1
			left=v[i].first;    // 新合并区间的左端点
			right=v[i].second;  // 新合并区间的右端点
		}
		// 注意:这里left虽然更新了,但在后续判断中实际没有使用
		// 因为已排序,后面的区间左端点一定≥当前left
	}
	
	cout<<cnt;  // 输出合并后的区间个数
	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值