竞赛常用库函数(二)(最值查找篇)

文章介绍了C++中的min、max函数及其变体min_element和max_element,用于查找数组中的最小/最大值,以及nth_element用于部分排序。还讨论了如何使用这些函数计算考试的最高分、最低分和平均分,以及避免强制类型转换的最佳实践。
摘要由CSDN通过智能技术生成
  • 1.min和max函数
  • min(a,b)返回a和b中较小的那个值,只能传入两个值,或传入一个列表。
min(3,5)=3;
min({1,2,3,4})=1;
  • max(a,b)返回a和b中较大的那个值,只能传入两个值,或传入一个列表。
max(8,5)=8;
max({1,2,3,4})=4;

 ### 时间复杂度为0(1),传入参数为数组时,时间复杂度为0(n),n为数组大小(min,max函数是在取最值操作时最常用的操作)

 2.min_element和max_element函数

  • min_element(st,ed)返回值地址[st,ed)中最小的那个值的地址(迭代器),传入参数为两个地址或迭代器 
  • max_element(st,ed)返回值地址[st,ed)中最大的那个值的地址(迭代器),传入参数为两个地址或迭代器  
//初始化v
vector<int>v={5,9,3,1,11};
//输出最大的元素,*表示解引用,即通过地址(迭代器)得到值
cout<<*max_element(v.begin(),v.end())<<"\n"; //输出11 

###时间复杂度均为0(n),n为数组大小(由传入的参数决定)

  • max和max_element的区别(min和min_element的区别)
#include <iostream>
#include <algorithm>
using namespace std;
int main(void)
{
	int a[6] = {5,3,2,4,6,1};
	int b = a[0];
	int c = a[1];
	cout<<max(b, c)<<" "<<min(b,c)<<endl; //输出为5 3
	cout<<max_element(a,a+6) - a<<endl;// 输出为4 
	cout<<*max_element(a,a+6)<<endl;//输出为 6 
	cout<<min_element(a,a+6) - a<<endl;// 输出为5
	cout<<*min_element(a,a+6)<<endl;	 //输出为1 
	return 0; 
}

 ### 这段代码中不加‘*’,max_element和min_element的返回值减去数组头地址,输出分别为4和5,这个4和5就是数组中最大元素(最小元素)在这个数组的下标


 ###小结max()和min()比较常规,而用好max_element和min_element可以省去编程中许多重复繁琐的步骤,以下是三个基础应用(min_element同理)

a=max_element(a, a + n)-a; //a代表数列中最大值的下标 
b=man_element(a, a + n); //b代表数列中最大的值的地址
c=*man_element(a, a + n); //c代表数列中最大的值

 

3.nth_element函数 

  • nth_element(st,k,ed) //进行部分排序,返回值为void()
  • 传入参数为三个地址或迭代器(其中第二个参数位置的元素将处于正确的位置,其他位置元素的顺序可能是任意的,但前面的都比它小,后面的都比它大) 
  • 时间复杂度0(n) 
//初始化v
vector<int>v={5,1,7,3,10,18,9};
//输出最大的元素,*表示解引用,即通过地址(迭代器)得到值
nth_element(v.begin(),v.begin()+3,v.end())<<"\n";
//这里v[3]的位置将会位于排序后的位置,其他的任意
for(auto &i:v){
	cout<<i<<' ';
} //输出3 1 5 7 9 18 10
​

### 这里v.begin()+3,那么v[3]位置的元素就是正确的(即第四大的数在这个位置,就是7),而且7左边都小于等于7,右边都大于等于7(除v[3]这个位置其他位置都是无序的)


 例题:每个学生得分都是0到100的整数,计算这次考试的最高分,最低分和平均分(1<=n<=1e4)

  • 使用max_element和min_element
#include<bits/stdc++.h>
using namespace std;
using ll=long long;//这行的效果和typedef long long ll是相同的,using可以代替typedef来进行重命名 
const int N=1e4+10;
int a[N];
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n;
	cin>>n;
	for(int i=0;i<n;++i){
		cin>>a[i];
	}
	cout<<*max_element(a,a+n)<<"\n";
	cout<<*min_element(a,a+n)<<"\n";
	
	ll sum=0;
	for(int i=0;i<n;++i){
		sum+=a[i];
	}
	cout<<fixed<<setprecision(2)<<1.0*sum/n<<"\n";
	return 0; 
}
  • 使用min和max自己实现取最大、最小
#include<bits/stdc++.h>
using namespace std;
using ll=long long;//这行的效果和typedef long long ll是相同的,using可以代替typedef来进行重命名 
const int N=1e4+10;
int a[N];
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n;
	cin>>n;
	for(int i=0;i<n;++i){
		cin>>a[i];
	}
	
	ll mx=a[0],mi=a[0];
	for(int i=0;i<n;++i){
		mx=max(mx,(ll)a[i]); //mx是ll类型,a是int类型,这里要进行常数类型转换 
		mi=min(mi,1ll*a[i]); //这样也可以*1ll之后就转换为long long类型了 
	}
	cout<<mx<<"\n"<<mi<<"\n"; 
	ll sum=0;
	for(int i=0;i<n;++i){
		sum+=a[i];
	}
	cout<<fixed<<setprecision(2)<<1.0*sum/n<<"\n";
	return 0; 
}

###这里不会有溢出的可能,直接改成int也可以

    int mx=a[0],mi=a[0];
	for(int i=0;i<n;++i){
		mx=max(mx,a[i]); 
		mi=min(mi,a[i]);
	}

  • 尽量避免进行强制类型转换

强制类型转换意味着关闭或挂起了编译器正常的类型检查功能,即编译器在强制类型转换发生处并不会发出警告,最好别用强制类型转换,不用强制类型转换也可以也出很好的C++程序

  • 27
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值