6.9 algorithm头文件下常用函数
6.9.1 max()、min()、abs()
max(x,y)和min(x,y)分别返回x和y中的最大值和最小值,且参数必须是两个(可以是浮点数)。如果想要返回三个数x、y、z的最大值,可以使用max(x , max(y,z))的写法。
abs(x)返回x的绝对值。注意:x必须是整数,浮点型的绝对值请用math头文件下的fabs()。
6.9.2 swap()
swap(x,y)用来交换x和y的值
int a = 1 , b = 2 ;
swap(a,b);
//此时a=2,b=1
6.9.3 reverse()
reverse(it , it2)可以将数组指针[it , it2)之间的元素或容器的迭代器在[it , it2)范围内的元素进行反转。
int a[10] = {10,11,12,13};
//将a[0]~a[3]反转
reverse(a , a+4)
6.9.4 next_permutation()
next_permutation()给出一个序列在全排列中的下一个序列
例如,当n==3时的全排列为
123
132
213
231
312
321
这样231的下一个序列就是312
int a[10] = {1,2,3} ;
do{
cout << a[0] << a[1] << a[2] <<endl ;
}while( next_permutation(a , a+3) )
使用循环是因为next_permutation在已经到达全排列的最后一个时会返回false
6.9.5 fill()
fill(start , end , val)可以把数组或容器中的某一段区间[start , end)赋为某个相同的值val。和memset不同,这里的赋值可以是数组类型对应范围中的任意值。
int a[5] = {1,2,3,4,5} ;
fill( a , a+5 , 233 ) ;
//a[0]~a[4]的值被设置为233
6.9.6 sort()
sort是用来排序的函数,他根据具体情形使用不同的排序算法,效率很高。sort在实现中规避了经典快速排序中可能出现的会导致实际复杂度为O(N²)的极端情况。
1.如何使用sort
加上头文件和命名空间
#include<algorithm>
using namespace std ;
使用方式为
sort( 首元素地址(必填) , 尾元素地址的下一个(必填) , 比较函数(选填) ) ;
如果不写比较换数,则默认对前面给出区间进行递增排序。
int a[9] = {9,4,2,5,6,-1} ;
//对a[0]~a[3]从小到大排序
sort(a , a+4);
//a为2,4,5,9,6,-1
sort的第三个可选参数是compare函数(一般写作cmp),用来实现比较规则。
2.如何实现比较规则
对基本数据类型、结构体类型、STL容器进行自定义规则排序的cmp写法:
(1)基本数据类型数组的排序
如果想要从大到小排序,则要使用比较函数cmp来告诉sort函数何时要交换元素。
bool cmp( int a, int b ){
return a > b ;
}
int main(){
int a[] = {3,1,4,2};
sort( a, a+4 , cmp ) ;
return
}
(2)结构体数组的排序
现定义如下结构体:
struct node{
int x ;
int y ;
}ssd[10];
如果想将ssd先按x从大到小排,当x相等的情况下,按照y从小到大排,写法为
bool cmp( node a , node b ){
if( a.x != b.x ){
return a.x > b.x ;
}
else{
return a.y < b.y ;
}
}
(3)容器的排序
在STL标准容器中,只有vector、string、deque是可以使用sort的。
bool cmp( int a , int b ){ //因为vector中的元素为int
return a > b ;
}
int main(){
sort( vi.begin() , vi.end() , cmp ) ;
return 0 ;
}
6.9.7 lower_bound()和upper_bound()
lower_bound()和upper_bound()需要在一个有序数组或容器中。
lower_bound(first , last , val)用来寻找在数组或容器的[first , last)范围内第一个大于等于val的元素的值,如果是数组,则返回该位置的指针;如果是容器,则返回该位置的迭代器。
upper_bound(first , last , val)用来寻找在数组或容器的[first , last)范围内第一个大于val的元素的值,如果是数组,则返回该位置的指针;如果是容器,则返回该位置的迭代器。
显然,如果数组或容器中没有需要寻找的元素,upper_bound()和lower_bound()均返回可以插入该元素的位置的指针或迭代器。
int a[10] = {1,2,3,3,3,3,5,5,5,5} ;
int* lowerPos = lower_bound(a , a+10 , -1) ;
int* upperPos = upper_bound(a , a+10 , -1) ;
cout << lowerPos - a << " " << upperPos - a << endl;
//输出0 0
int* lowerPos1 = lower_bound(a , a+10 , 3) ;
int* upperPos1 = upper_bound(a , a+10 , 3) ;
cout << lowerPos1 - a << " " << upperPos1 - a << endl;
//输出2 6
显然,如果只是获得预查元素的下标,就可以不使用临时指针,而直接令返回值减去数组首地址即可。