algorithm 头文件常用函数
本文介绍 C++ 的 algorithm 库中常用函数。algorithm是C++标准程序库中的一个头文件,定义了C++ STL标准中的基础性的算法(均为函数模板)。定义了设计用于元素范围的函数集合。任何对象序列的范围可以通过迭代器或指针访问。
<1>序列容器遍历操作
常用参数对照:
frist : 起点,为一个迭代器
last : 终点,为一个迭代器
for_each
函数原型:
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function fn)
功能: 遍历序列容器,将区间[fist,last)之内每一个元素传入函数fn,在函数fn内对元素进行操作;
示例:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//遍历数组vector,修改vector里的所有元素值为5,输出元素
void fn(int &item)
{
item = 5;
cout << item << endl;
}
int main()
{
int a[] = {1,2,3,4,5,6,7};
vector<int> v(a,a+7);
for_each(v.begin(),v.end(),fn);
}
find
函数原型:
template<class InputIterator, class T>
InputIterator find (InputIterator first, InputIterator last, const T& val)
{
while (first!=last) {
if (*first==val) return first;
++first;
}
return last;
}
功能: 返回一个迭代器,该迭代器返回等于val
的范围内的第一个元素的迭代器。如果找不到这样的元素,则函数返回last
迭代器。
示例:
int a[] = {1,2,3,4,5,6,7};
vector<int> v(a,a+7);
vector<int>::iterator it = find(v.begin(),v.end(),5);//*it = 5
it = find(v.begin(),v.end(),9);//*it = 0
find_if
函数原型:
template<class InputIterator, class UnaryPredicate>
InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred)
{
while (first!=last) {
if (pred(*first)) return first;
++first;
}
return last;
}
功能: 将区间[fist,last)之内每一个元素传入一元判断式:当pred(elem) 返回true时返回第一个达成条件的元素迭代器;
示例:
int a[] = {1,4,6,2,5,3,7};
vector<int> v(a,a+7);
vector<int>::iterator it = find_if(v.begin(),v.end(),fun);//*it = 6
equal
函数原型:
template <class InputIterator1, class InputIterator2>
bool equal ( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2 )
{
while (first1!=last1) {
if (!(*first1 == *first2)) // or: if (!pred(*first1,*first2)), for version 2
return false;
++first1; ++first2;
}
return true;
}
功能: 比较两个序列的逐个元素是否相等;
count
函数原型:
template <class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type
count (InputIterator first, InputIterator last, const T& val)
{
typename iterator_traits<InputIterator>::difference_type ret = 0;
while (first!=last) {
if (*first == val) ++ret;
++first;
}
return ret;
}
功能: 返回序列中等于给定值元素的个数;
示例:
int a[] = {1,4,6,4,5,3,7};
vector<int> v(a,a+7);
//把所有的三的倍数替换为 8
replace_if(v.begin(),v.end(),fun,8); //v = [1 4 8 4 5 8 7]
<2> 序列修改操作
swap
函数原型:
template <class T> void swap ( T& a, T& b )
{
T c(a); a=b; b=c;
}
函数功能:交换a和b
replace
函数原型:
template <class ForwardIterator, class T>
void replace (ForwardIterator first, ForwardIterator last,
const T& old_value, const T& new_value)
{
while (first!=last) {
if (*first == old_value) *first=new_value;
++first;
}
}
功能: 把序列中等于old_value元素替换为 new_value;
示例:
int a[] = {1,4,6,5,5,3,7};
vector<int> v(a,a+7);
replace(v.begin(),v.end(),5,55);//把5替换成55
replace_if
函数原型:
template < class ForwardIterator, class UnaryPredicate, class T >
void replace_if (ForwardIterator first, ForwardIterator last,
UnaryPredicate pred, const T& new_value)
{
while (first!=last) {
if (pred(*first)) *first=new_value;
++first;
}
}
功能: 将区间[fist,last)之内每一个元素传入一元判断式:当pred(elem) 返回true时的元素替换成new_value;
示例代码:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
//把小于5的替换为8
bool fun(int i)
{
return i < 5;
}
int main()
{
int a[] = {1,2,3,4,5,6,7};
vector<int> vec(a,a+7);
replace_if(vec.begin(),vec.end(),fun,8); //vec = [8 8 8 8 5 6 7]
return 0;
}
序列排序
sort
函数原型:
template <class RandomAccessIterator>
void sort (RandomAccessIterator first, RandomAccessIterator last);
template <class RandomAccessIterator, class Compare>
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
函数功能:
两个重载: 第一个对first到last 升序排序
第二个在第一个基础上传入一个传入一元判断式comp为a < b则升序,否则降序
示例:
bool fun(int a,int b)
{
return a < b; // a < b : vec = 1 2 3 4 5 6 7
// a > b : vec = 7 6 5 4 3 2 1
}
int main()
{
int a[] = {1,3,2,4,6,7,5};
vector<int> vec(a,a+7);
sort(vec.begin(),vec.end(),fun); //vec = [1 2 3 4 5 6 7]
return 0;
}
排列函数
next_permutation
函数原型:
bool next_permutation(iterator start,iterator end)
函数功能:
求的是序列当前排列的下一个排列,当当前序列不存在下一个排列时,函数返回false,否则返回true。
注意: next_permutation() 在使用前需要对欲排列数组按升序排序,否则只能找出该序列之后的全排列数。
代码:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int num[3]={1,2,3};
do
{
cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<endl;
}while(next_permutation(num,num+3));
return 0;
}
输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
需要强调的是,next_permutation() 在使用前需要对欲排列数组按升序排序,否则只能找出该序列之后的全排列数。
下面的代码将展示如何使用next_permutation
在接收一个数组p之后对数组p的内容进行全排列,其中n代表数组长度:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
int n,p[10];
scanf("%d",&n);
for(int i = 0;i < n;i ++)
{
scanf("%d",&p[i]);
}
sort(p,p+n); //事先排序以保证全排列
do
{
for(int i = 0;i < n;i ++)
{
printf("%d ",p[i]);//对于排好序的数组,直接输出即为第一个排列
}
printf("\n");
}while(next_permutation(p,p+n));
return 0;
}