- 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++程序