algorithm
使用algorithm头文件,需要在头文件下面加一行“using namespace std”,才能使用。
algorithm的常用函数(1) max(),min(),abs()
max(x,y)和min(x,y)分别返回x和y的最大值和最小值,且参数必须是两个(可以是浮点数),如果要返回三个数x,y,z的最大值,可以使用max(max(x,y),z)的写法。abs(x)返回x的绝对值。注意,x必须是整数,浮点型的绝对值要用math头文件下的fabs。int x = -1, y = 2 ;
cout << max(x,y) << ' ' << min(x,y) << endl ;
cout << abs(x) << ' ' << abs(y) << endl ;
输出结果:2 -1
1 2(2) swap()
swap(x,y)用来交换x和y的值int x = 3, y = 5 ;
swap(x,y) ;
cout << "x = " << x << ",y = " << y << endl ;
输出结果:x = 5,y = 3(3) reverse()
reverse(it1,it2)可以将数组指针或者容器的迭代器在[it1,it2)范围内的元素进行反转。int v1[ ] = {3,1,2,5,4} ;
vectorv2(v1,v1+5) ;
reverse(v1,v1+5) ;
reverse(v2.begin(),v2.begin()+2) ;
for(auto ele : v1) cout << ele << ' ' ;
cout << endl ;
for(auto ele : v2) cout << ele << ' ' ;
cout << endl ;
输出结果:4 5 2 1 3
1 3 2 5 4(4) next_permutation()
next_permutation()给出一个序列全排列中的下一个序列。使用的方式和reverse类似。
例如,当n==3时的全排列为
123,132,213,231,312,321,这样231的下一个序列就是312。int a[ ] = {1,2,3} ;
do{
cout << a[0] << a[1] << a[2] << endl ;
}while(next_permutation(a,a+3)) ;
输出结果:123
132
213
231
312
321
注意,这里要用do..while否则输出的结果中会少123这种情况。
(5) fill()
fill()函数可以把数组或者容器中的某一段区域赋为某个相同的值。和memset不同的是,这里的赋值可以是和数组类型对应范围中的任意值。int a[ ] = {3,1,2,5,4} ;
fill(a,a+2,888) ;
for(auto e : a) cout << e << ' ' ;
cout << endl ;
输出结果:888 888 2 5 4
(6) sort()
sort()是用来排序的。sort()的使用方式是,sort(首元素地址(必填),尾元素地址的下一个地址(必填),比较函数(非必填))。如果不写比较函数,则默认对给出的区间进行递增排序。int a[ ] = {3,1,2,5,4} ;
sort(a,a+2) ;
for(auto e : a) cout << e << ' ' ;
puts(" ") ;
sort(a,a+5) ;
for(auto e : a) cout << e << ' ' ;
cout << endl ;
输出结果:1 3 2 5 4
1 2 3 4 5
实现从大到小排序(char,doubel等基本类型与int类似)bool cmp(int a,int b){
return a>b ;
}
int main(){
int a[] = {3,1,2,5,4} ;
sort(a,a+2,cmp) ;
for(auto e : a) cout << e << ' ' ;
puts("") ;
sort(a,a+5,cmp) ;
for(auto e : a) cout << e << ' ' ;
cout << endl ;
return 0 ;
}
输出结果:3 1 2 5 4
5 4 3 2 1
结构体的排序,具体看cmp的编写方式。const int N = 5 ;
struct point{
int x,y ;
}a[N];bool cmp(point a,point b){
return a.x>b.x ;
}
int main(){
a[0].x = 2 ;
a[0].y = 3 ;
a[1].x = 1 ;
a[1].y = 4 ;
a[2].x = 2 ;
a[2].y = 5 ;
sort(a,a+3,cmp) ;
for(int i=0;i<3;i++){
printf("%d %d\n",a[i].x,a[i].y) ;
}
return 0 ;
}
输出结果:2 3
2 5
1 4
如果要按照x从大到小排序,在x相等的时候按照y从小到大排序。struct point{
int x,y ;
}a[N];bool cmp(point a,point b){
if(a.x != b.x) return a.x > b.x ;
else return a.y < b.y ;
}int main(){
a[0].x = 2 ;
a[0].y = 3 ;
a[1].x = 1 ;
a[1].y = 4 ;
a[2].x = 2 ;
a[2].y = 5 ;
sort(a,a+3,cmp) ;
for(int i=0;i<3;i++){
cout << a[i].x << " " << a[i].y << endl ;
}
return 0 ;
}
输出结果:2 3
2 5
1 4
最后举个很有意思的例子,怎么样实现按照字符串的长度排序。bool cmp(string str1,string str2){
return str1.size() < str2.size() ;
}int main(){
string a[] = {"cccc","zz","bbb","aa"} ;
sort(a,a+4,cmp) ;
for(int i=0;i<4;i++){
cout << a[i] << endl ;
}
return 0 ;
}
输出结果:zz
aa
bbb
cccc
实现了按照字符串的长度排序,但是如果当长度相同按字典序排,如何实现?bool cmp(string str1,string str2){
if(str1.size() != str2.size()) return str1.size() < str2.size() ;
else return str1 < str2 ;
}int main(){
string a[] = {"cccc","zz","bbb","aa"} ;
sort(a,a+4,cmp) ;
for(int i=0;i<4;i++){
cout << a[i] << endl ;
}
return 0 ;
}
输出结果:aa
zz
bbb
cccc(7) lower_bound()和upper_bound()
lower_bound()和upper_bound()需要用在一个有序数组或者容器中。
Lower_bound(st,ed,val)用来寻找在数组或者容器中的[st,ed)范围内第一个值大于等于val的元素的位置,如果是数组,则返回该位置的指针,如果是容器则返回该位置的迭代器。
Upper_bound(st,ed,val)用来寻找在数组或者容器中的[st,ed)范围内的第一个大于val的元素的位置,如果是数组,则返回该位置的指针,如果是容器,则返回该位置的迭代器。int a[10] = {1,2,2,3,3,3,5,5,5,5} ;
//search -1
int* lp = lower_bound(a,a+10,-1) ;
int* up = upper_bound(a,a+10,-1) ;
cout << lp - a << ' ' << up - a << endl ;
//search 1
lp = lower_bound(a,a+10,1) ;
up = upper_bound(a,a+10,1) ;
cout << lp - a << ' ' << up - a << endl ;
//search 3
lp = lower_bound(a,a+10,3) ;
up = upper_bound(a,a+10,3) ;
cout << lp - a << ' ' << up - a << endl ;
//search 4
lp = lower_bound(a,a+10,4) ;
up = upper_bound(a,a+10,4) ;
cout << lp - a << ' ' << up - a << endl ;
//search 6
lp = lower_bound(a,a+10,6) ;
up = upper_bound(a,a+10,6) ;
cout << lp - a << ' ' << up - a << endl ;
输出结果:0 0
0 1
3 6
6 6
10 10
如果想要获得数组中欲查元素的下标,可以直接令`lower_bound()`和`upper_bound()`的返回值减去数组的首地址即可。如果查找的对象是容器,则返回的是对应的迭代器。