1、algorithm的简单介绍
c++之中的algorithm库包含了所有vector、list、set、map数据结构能想到的一些函数,例如查找,替换,排序,计数等常用的功能的。
官网的链接:http://www.cplusplus.com/reference/algorithm/ 可以直接的学习。
2、algorithm常用的函数介绍
2.1 max(),min(),abs()
max(x,y)和min(x,y)参数必须是两个,如果想比较x,y,z的最大值,可写为max(x,max(y,z))。
abs(x) 返回x的绝对值。x必须为整数,浮点型的绝对值要用math头文件下的fabs。
2.2 swap()
swap(x,y)交换x,y的数值
2.3 reverse()
reverse(it,it2) 可以将数组指针在[it,it2)之间的元素或容器的迭代器在[it,it2)范围内的元素进行反转。
#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
int a[10]={10,11,12,13,14,15};
reverse(a,a+4);
for(int i=0;i<6;i++){
printf("%d ",a[i]);
}
return 0;
}
输出:13 12 11 10 14 15
#include<stdio.h>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
string str="abcdefghi";
reverse(str.begin()+2,str.begin()+6);
for(int i=0;i<str.length();i++){
printf("%c",str[i]);
}
return 0;
}
输出:abfedcghi
2.4 next_permutation()
next_permutation() 给出一个序列在全排列中的下一个序列。
#include<stdio.h>
#include<string>
#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;
}
输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
2.5 fill()
fill() 可以把数组或容器中的某一段区间赋为某个相同的值。和memset不同,这里的赋值可以使数组类型对应范围中的任意值。
#include<stdio.h>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
int a[10]={1,2,3,4,5};
fill(a,a+5,233);
for(int i=0;i<5;i++){
printf("%d ",a[i]);
}
return 0;
}
输出:233 233 233 233 233 每一个都是233了
2.6 sort()
其余参考:C++ sort排序函数用法 C++ sort 排序(降序、升序)使用总结
例子:
默认为递增排序
- 若要递减排序,需要增加比较函数
bool cmp(int a,int b){
return a>b;
}
sort(a,a+n,cmp);
struct node{
int x,y;
}a[10];
bool cmp(node a,node b){
return a.x>b.x;
}
//
bool cmp(int x,int y){
if(a.x!=b.x) return a.x>b.x;
else return a.y<b.y;
}
- 对于递增和递减,标准库里已经有现成的了,就在functional里,include进来就行了。functional提供了一堆基于模板的比较函数对象。它们是(看名字就知道意思了):equal_to、not_equal_to、greater、greater_equal、less、less_equal。普通的问题,greater和less就足够了,直接拿过来用:
升序:sort(begin,end,less<data-type>());
降序:sort(begin,end,greater<data-type>()). //letcode 刷题用过,有效果的
#include<stdio.h>
#include<string>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
int main()
{
int a[20]={2,4,1,23,5,76,0,43,24,65},i;
for(i=0;i<20;i++)
cout<<a[i]<<" ";
cout<<endl;
sort(a,a+20,greater<int>());
for(i=0;i<20;i++)
cout<<a[i]<<" ";
cout<<endl;
sort(a,a+20,less<int>());
for(i=0;i<20;i++)
cout<<a[i]<<" ";
cout<<endl;
return 0;
}
输出:
2 4 1 23 5 76 0 43 24 65 0 0 0 0 0 0 0 0 0 0
76 65 43 24 23 5 4 2 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 2 4 5 23 24 43 65 76
- 容器排序,在STL标砖容器中,只有vector/string/deque可以sort
#include<stdio.h>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
bool cmp(int a,int b){
return a>b;
}
int main()
{
vector<int> vi;
vi.push_back(3);
vi.push_back(1);
vi.push_back(2);
sort(vi.begin(),vi.end(),cmp);
for(int i=0;i<3;i++){
printf("%d ",vi[i]);
}
return 0;
}
输出:3 2 1
2.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元素的位置,如果是数组,返回该位置的指针;如果是容器,返回该位置的迭代器。
#include<stdio.h>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int a[10]={1,2,2,3,3,3,5,5,5,5};
printf("%d,%d\n",lower_bound(a,a+10,3)-a,upper_bound(a,a+10,3)-a);
return 0;
}
**注意其中的 -a**
输出:3,6
3、algorithm其余常用的函数介绍
3.1 不修改内容的序列操作
adjacent_find 查找两个相邻(Adjacent)的等价(Identical)元素
all_ofC++11 检测在给定范围中是否所有元素都满足给定的条件
any_ofC++11 检测在给定范围中是否存在元素满足给定条件
count 返回值等价于给定值的元素的个数
count_if 返回值满足给定条件的元素的个数
equal 返回两个范围是否相等
find 返回第一个值等价于给定值的元素
find_end 查找范围A中与范围B等价的子范围最后出现的位置
find_first_of 查找范围A中第一个与范围B中任一元素等价的元素的位置
find_if 返回第一个值满足给定条件的元素
find_if_notC++11 返回第一个值不满足给定条件的元素
for_each 对范围中的每个元素调用指定函数
mismatch 返回两个范围中第一个元素不等价的位置
none_ofC++11 检测在给定范围中是否不存在元素满足给定的条件
search 在范围A中查找第一个与范围B等价的子范围的位置
search_n 在给定范围中查找第一个连续n个元素都等价于给定值的子范围的位置
3.2 修改内容的序列操作
copy 将一个范围中的元素拷贝到新的位置处
copy_backward 将一个范围中的元素按逆序拷贝到新的位置处
copy_ifC++11 将一个范围中满足给定条件的元素拷贝到新的位置处
copy_nC++11 拷贝 n 个元素到新的位置处
fill 将一个范围的元素赋值为给定值
fill_n 将某个位置开始的 n 个元素赋值为给定值
generate 将一个函数的执行结果保存到指定范围的元素中,用于批量赋值范围中的元素
generate_n 将一个函数的执行结果保存到指定位置开始的 n 个元素中
iter_swap 交换两个迭代器(Iterator)指向的元素
moveC++11 将一个范围中的元素移动到新的位置处
move_backwardC++11 将一个范围中的元素按逆序移动到新的位置处
random_shuffle 随机打乱指定范围中的元素的位置
remove 将一个范围中值等价于给定值的元素删除
remove_if 将一个范围中值满足给定条件的元素删除
remove_copy 拷贝一个范围的元素,将其中值等价于给定值的元素删除
remove_copy_if 拷贝一个范围的元素,将其中值满足给定条件的元素删除
replace 将一个范围中值等价于给定值的元素赋值为新的值
replace_copy 拷贝一个范围的元素,将其中值等价于给定值的元素赋值为新的值
replace_copy_if 拷贝一个范围的元素,将其中值满足给定条件的元素赋值为新的值
replace_if 将一个范围中值满足给定条件的元素赋值为新的值
reverse 反转排序指定范围中的元素
reverse_copy 拷贝指定范围的反转排序结果
rotate 循环移动指定范围中的元素
rotate_copy 拷贝指定范围的循环移动结果
shuffleC++11 用指定的随机数引擎随机打乱指定范围中的元素的位置
swap 交换两个对象的值
swap_ranges 交换两个范围的元素
transform 对指定范围中的每个元素调用某个函数以改变元素的值
unique 删除指定范围中的所有连续重复元素,仅仅留下每组等值元素中的第一个元素。
unique_copy 拷贝指定范围的唯一化(参考上述的 unique)结果
3.3 划分操作
is_partitionedC++11 检测某个范围是否按指定谓词(Predicate)划分过
partition 将某个范围划分为两组
partition_copyC++11 拷贝指定范围的划分结果
partition_pointC++11 返回被划分范围的划分点
stable_partition 稳定划分,两组元素各维持相对顺序
3.4 排序操作
is_sortedC++11 检测指定范围是否已排序
is_sorted_untilC++11 返回最大已排序子范围
nth_element 部份排序指定范围中的元素,使得范围按给定位置处的元素划分
partial_sort 部份排序
partial_sort_copy 拷贝部分排序的结果
sort 排序
stable_sort 稳定排序
3.5 二分查找操作
binary_search 判断范围中是否存在值等价于给定值的元素
equal_range 返回范围中值等于给定值的元素组成的子范围
lower_bound 返回指向范围中第一个值大于或等于给定值的元素的迭代器
upper_bound 返回指向范围中第一个值大于给定值的元素的迭代器
3.6 集合操作
includes 判断一个集合是否是另一个集合的子集
inplace_merge 就绪合并
merge 合并
set_difference 获得两个集合的差集
set_intersection 获得两个集合的交集
set_symmetric_difference 获得两个集合的对称差
set_union 获得两个集合的并集
3.7 堆操作
is_heap 检测给定范围是否满足堆结构
is_heap_untilC++11 检测给定范围中满足堆结构的最大子范围
make_heap 用给定范围构造出一个堆
pop_heap 从一个堆中删除最大的元素
push_heap 向堆中增加一个元素
sort_heap 将满足堆结构的范围排序
3.8最大最小操作
is_permutationC++11 判断一个序列是否是另一个序列的一种排序
lexicographical_compare 比较两个序列的字典序
max 返回两个元素中值最大的元素
max_element 返回给定范围中值最大的元素
min 返回两个元素中值最小的元素
min_element 返回给定范围中值最小的元素
minmaxC++11 返回两个元素中值最大及最小的元素
minmax_elementC++11 返回给定范围中值最大及最小的元素
next_permutation 返回给定范围中的元素组成的下一个按字典序的排列
prev_permutation 返回给定范围中的元素组成的上一个按字典序的排列
参考文章:algorithm头文件下常用函数