C++ STL 学习| algorithm头文件下的常用函数
algorithm头文件下的常用函数
max()、min()和abs()
max(x, y)和min(x, y)分别返回x和y中的最大值和最小值,且参数必须是两个,可以是浮点数。
abs(x)返回x的绝对值,x必须是整数,浮点型的绝对是需要用mayh头文件下的fabs
swap()
swap(x, y)交换x和y的值。
reverse()
reverse(it1, it2)可以将数组指针在[it1, it2)之间的元素或容器的迭代器在[it1, it2)范围内的元素进行翻转。
next_permutation()
next_permutation()给出一个序列在全排列中的下一个序列。
#include<stdio.h>
#include<algorithm>
using namespace std;
int main() {
int a[10] = {1,2,3};
do{
printf("%d%d%d\n", a[0],a[1],a[2]);
}while(next_permutation(a, a+3));
return 0;
}
输出结果为:
123
132
213
231
312
321
fill()
fill()可以把数组或容器中的某一段区间赋为某个相同的值。和memset不同,此处赋值可以是数组类型对应范围中的任意值。
#include<stdio.h>
#include<algorithm>
using namespace std;
int main() {
int a[5] = {1,2.3,4,5};
fill(a, a+5, 233); //将a[0]~a[4]均赋值为233
for(int i = 0; i < 5; i++) {
printf("%d ", a[i]);
}
return 0;
}
sort()
排序函数,在使用时需加上头文件#include<algorithm>
和using namespace std;
使用方式为
sort(首元素的地址(必填), 尾元素地址的下一个地址(必填), 比较函数(非必填));
srot的参数有三个,前两个必填,比较函数可根据需要进行填写。
1.如果不写比较函数,则默认对前面给出的区间进行递增排序。
#include<stdio.h>
#include<algorithm>
using namespace std;
int main() {
int a[6] = {9,4,2,5,6,-1};
sort(a, a + 4);
for(int i = 0; i < 6; i++) {
printf("%d ", a[i]);
}
printf("\n");
sort(a, a + 6);
for(int i = 0; i < 6; i++) {
printf("%d ", a[i]);
}
return 0;
}
2.实现比较函数cmp
(1)基本数据类型数组的排序
如果想要从大到小进行排序,使用比较函数cmp来进行说明,此处比较int型,可以这样写:
#include<stdio.h>
#include<algorithm>
using namespace std;
bool cmp(int a, int b) {
return a > b; //可以理解为当a > b时把a放到b前面
}
int main() {
int a[] = {3,1,4,2};
sort(a, a + 4, cmp);
for(int i = 0; i < 4; i++) {
printf("%d ", a[i]);
}
return 0;
}
(2)结构体数组的排序
定义结构体如下:
struct node {
int x, y;
}ssd[10];
如果想将ssd数组按照x从大到小排序(即进行一级排序),那么可以这样写cmp函数:
bool cmp(node a, node b) {
return a.x > b.x;
}
完整代码如下:
#include<stdio.h>
#include<algorithm>
using namespace std;
struct node {
int x,y;
}ssd[10];
bool cmp(node a, node b) {
return a.x > b.x;
}
int main() {
ssd[0].x = 2;
ssd[0].y = 2;
ssd[1].x = 1;
ssd[1].y = 3;
ssd[2].x = 3;
ssd[2].y = 1;
sort(ssd, ssd + 3, cmp); //排序
for(int i = 0; i < 3; i++) {
printf("%d %d\n", ssd[i].x, ssd[i].y);
}
return 0;
}
如果x相等的情况下,按照y的大小从小到大进行二级排序,则cmp这样写:
bool cmp(node a, node b){
if(a.x != b.x) return a.x > b.x;
else return a.y < b.y;
}
完整代码如下:
#include<stdio.h>
#include<algorithm>
using namespace std;
struct node {
int x,y;
}ssd[10];
bool cmp(node a, node b) {
if(a.x != b.x) return a.x > b.x;
else return a.y < b.y;
}
int main() {
ssd[0].x = 2;
ssd[0].y = 2;
ssd[1].x = 1;
ssd[1].y = 3;
ssd[2].x = 2;
ssd[2].y = 1;
sort(ssd, ssd + 3, cmp); //排序
for(int i = 0; i < 3; i++) {
printf("%d %d\n", ssd[i].x, ssd[i].y);
}
return 0;
}
(3)容器的排序
在STL标准容器中,只有vector、string、deque是可以使用sort的,这是因为set、map这种容器是用红黑树实现的,元素本身有序,不允许使用sort进行排序。
如对string进行排序
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main() {
string str[3] = {"ab","aaaa","b"};
sort(str, str + 3);
for(int i = 0; i < str.size(); i++) {
cout << str[i] << endl;
}
return 0;
}
输出为:
aaaa
ab
b
lower_bound()和upper_bound()
lower_bound()和upper_bound()需要用在一个有序数组或容器中。
lower_bound(first, last, val)用来寻找在数组或容器的[first, last)范围内第一个值大于等于val元素的位置,如果是数组,则返回该位置的指针;如果是容器,则返回该位置的迭代器。
upper_bound(first, last, val)用来寻找在数组或容器的[first, last)范围内第一个值大于val元素的位置,如果是数组,则返回该位置的指针;如果是容器,则返回该位置的迭代器。
而如果数组或容器中没有寻找的元素,则lower_bound()和upper_bound()均返回可以插入该元素的位置的指针或迭代器。lower_bound()和upper_bound()的复杂度均为O(log(last - first))。
#include<stdio.h>
#include<algorithm>
using namespace std;
int main() {
int a[10] = { 1,2,2,3,3,3,5,5,5,5 };
//目标为寻找-1
int* lowerPos = lower_bound(a, a + 10, -1);
int* upperPos = upper_bound(a, a + 10, -1);
printf("%d, %d\n", lowerPos - a, upperPos - a);
//寻找1
lowerPos = lower_bound(a, a + 10, 1);
upperPos = upper_bound(a, a + 10, 1);
printf("%d, %d\n", lowerPos - a, upperPos - a);
//寻找3
lowerPos = lower_bound(a, a + 10, 3);
upperPos = upper_bound(a, a + 10, 3);
printf("%d, %d\n", lowerPos - a, upperPos - a);
//寻找4
lowerPos = lower_bound(a, a + 10, 4);
upperPos = upper_bound(a, a + 10, 4);
printf("%d, %d\n", lowerPos - a, upperPos - a);
//寻找6
lowerPos = lower_bound(a, a + 10, 6);
upperPos = upper_bound(a, a + 10, 6);
printf("%d, %d\n", lowerPos - a, upperPos - a);
return 0;
}