目录
1.STL算法库
2.非修改式序列算法
3.修改式序列算法
4.排序和相关算法
5.通用数值算法
0。参观一下STL有些什么算法:
<algorithm>
- adjacent_find
- all_of
- any_of
- binary_search
- copy
- copy_backward
- copy_if
- copy_n
- count
- count_if
- equal
- equal_range
- fill
- fill_n
- find
- find_end
- find_first_of
- find_if
- find_if_not
- for_each
- generate
- generate_n
- includes
- inplace_merge
- is_heap
- is_heap_until
- is_partitioned
- is_permutation
- is_sorted
- is_sorted_until
- iter_swap
- lexicographical_compare
- lower_bound
- make_heap
- max
- max_element
- merge
- min
- minmax
- minmax_element
- min_element
- mismatch
- move
- move_backward
- next_permutation
- none_of
- nth_element
- partial_sort
- partial_sort_copy
- partition
- partition_copy
- partition_point
- pop_heap
- prev_permutation
- push_heap
- random_shuffle
- remove
- remove_copy
- remove_copy_if
- remove_if
- replace
- replace_copy
- replace_copy_if
- replace_if
- reverse
- reverse_copy
- rotate
- rotate_copy
- search
- search_n
- set_difference
- set_intersection
- set_symmetric_difference
- set_union
- shuffle
- sort
- sort_heap
- stable_partition
- stable_sort
- swap
- swap_ranges
- transform
- unique
- unique_copy
- upper_bound
1.STL算法库
STL中的算法库分为四种:非修改式序列算法、修改式序列算法、排序和相关算法、通用数值算法。
2.非修改式序列算法
2.1 for_each()
参考[1]http://www.cplusplus.com/reference/algorithm/for_each/?kw=for_each
template<class _InIt,
class _Fn1> inline
_Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
{ // perform function for each element
_DEBUG_RANGE(_First, _Last);
_DEBUG_POINTER(_Func);
_For_each(_Unchecked(_First), _Unchecked(_Last), _Func);
return (_STD move(_Func));
}
功能:以区间[_First,_Last)中每一个元素为参数调用_Func函数。
// for_each example
#include <iostream> // std::cout
#include <algorithm> // std::for_each
#include <vector> // std::vector
void myfunction (int i) { // function:
std::cout << ' ' << i;
}
struct myclass { // function object type:
void operator() (int i) {std::cout << ' ' << i;}
} myobject;
int main () {
std::vector<int> myvector;
myvector.push_back(10);
myvector.push_back(20);
myvector.push_back(30);
std::cout << "myvector contains:";
for_each (myvector.begin(), myvector.end(), myfunction);
std::cout << '\n';
// or:
std::cout << "myvector contains:";
for_each (myvector.begin(), myvector.end(), myobject);
std::cout << '\n';
return 0;
}
输出:
myvector contains: 10 20 30
myvector contains: 10 20 30
2.2元素计数算法 count_if()
参考[1]http://www.cplusplus.com/reference/algorithm/count_if/?kw=count_if
函数原型:
template<class _InIt,
class _Pr> inline
typename iterator_traits<_InIt>::difference_type
count_if(_InIt _First, _InIt _Last, _Pr _Pred)
{ // count elements satisfying _Pred
_DEBUG_RANGE(_First, _Last);
_DEBUG_POINTER(_Pred);
return (_Count_if(_Unchecked(_First), _Unchecked(_Last), _Pred));
}
Returns the number of elements in the range [first,last)
for which pred is true.
// count_if example
#include <iostream> // std::cout
#include <algorithm> // std::count_if
#include <vector> // std::vector
bool IsOdd (int i) { return ((i%2)==1); }
int main () {
std::vector<int> myvector;
for (int i=1; i<10; i++) myvector.push_back(i); // myvector: 1 2 3 4 5 6 7 8 9
int mycount = count_if (myvector.begin(), myvector.end(), IsOdd);
std::cout << "myvector contains " << mycount << " odd values.\n";
return 0;
}
输出:
myvector contains 5 odd values.
2.3最小值和最大值算法
mim_element()
max_element()
template<class _FwdIt,
class _Pr> inline
_FwdIt min_element(_FwdIt _First, _FwdIt _Last, _Pr _Pred)
{ // find smallest element, using _Pred
_DEBUG_RANGE(_First, _Last);
_DEBUG_POINTER(_Pred);
return (_Rechecked(_First,
_Min_element(_Unchecked(_First), _Unchecked(_Last), _Pred)));
}
函数原型:
template <class ForwardIterator>
ForwardIterator min_element (ForwardIterator first, ForwardIterator last);
template <class ForwardIterator, class Compare>
ForwardIterator min_element (ForwardIterator first, ForwardIterator last,
Compare comp);
函数功能:
Returns an iterator pointing to the element with the smallest value in the range [first,last)
.
max_element()
template <class ForwardIterator>
ForwardIterator max_element (ForwardIterator first, ForwardIterator last);
template <class ForwardIterator, class Compare>
ForwardIterator max_element (ForwardIterator first, ForwardIterator last,
Compare comp);
函数功能:Returns an iterator pointing to the element with the largest value in the range [first,last)
.
求区间最大值最小值例子:
参考资料[1]http://www.cplusplus.com/reference/algorithm/max_element/
// min_element/max_element example
#include <iostream> // std::cout
#include <algorithm> // std::min_element, std::max_element
bool myfn(int i, int j) { return i<j; }
struct myclass {
bool operator() (int i,int j) { return i<j; }
} myobj;
int main () {
int myints[] = {3,7,2,5,6,4,9};
// using default comparison:
std::cout << "The smallest element is " << *std::min_element(myints,myints+7) << '\n';
std::cout << "The largest element is " << *std::max_element(myints,myints+7) << '\n';
// using function myfn as comp:
std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myfn) << '\n';
std::cout << "The largest element is " << *std::max_element(myints,myints+7,myfn) << '\n';
// using object myobj as comp:
std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myobj) << '\n';
std::cout << "The largest element is " << *std::max_element(myints,myints+7,myobj) << '\n';
return 0;
}
输出:
The smallest element is 2
The largest element is 9
The smallest element is 2
The largest element is 9
The smallest element is 2
The largest element is 9
2.4搜索算法
-
find()
-
find_if()
-
find_first_of()
-
find_end()
-
search()
-
search_n()
-
adjacent_find()
2.5区间比较算法
-
equal()
-
mismatch()
-
lexicographical_compare()
lexicographically:字典顺序地
template <class InputIterator1, class InputIterator2>
bool lexicographical_compare (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2);
template <class InputIterator1, class InputIterator2, class Compare>
bool lexicographical_compare (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
Compare comp);
Returns true
if the range [first1,last1)
compares lexicographically less than the range [first2,last2)
.
A lexicographical comparison is the kind of comparison generally used to sort words alphabetically in dictionaries; It involves comparing sequentially the elements that have the same position in both ranges against each other until one element is not equivalent to the other. The result of comparing these first non-matching elements is the result of the lexicographical comparison.
If both sequences compare equal until one of them ends, the shorter sequence is lexicographically less than the longer one.
The elements are compared using operator<
for the first version, and comp for the second. Two elements, a and b are considered equivalent if (!(a<b) && !(b<a))
or if (!comp(a,b) && !comp(b,a))
.
// lexicographical_compare example
#include <iostream> // std::cout, std::boolalpha
#include <algorithm> // std::lexicographical_compare
#include <cctype> // std::tolower
// a case-insensitive comparison function:
bool mycomp (char c1, char c2)
{ return std::tolower(c1)<std::tolower(c2); }//都换成小写的话apple>apartment
int main () {
char foo[]="Apple";
char bar[]="apartment";//A的字典序小于a,所以Apple<apartment
//A的字典序小于a,所以Apple<apartment apple>apartment
/* A的ASCII=65,a的ASCII码=97 ,所以A<a */
std::cout << std::boolalpha;
std::cout << "Comparing foo and bar lexicographically (foo<bar):\n";
std::cout << "Using default comparison (operator<): ";
std::cout << std::lexicographical_compare(foo,foo+5,bar,bar+9);
std::cout << '\n';
std::cout << "Using mycomp as comparison object: ";
std::cout << std::lexicographical_compare(foo,foo+5,bar,bar+9,mycomp);
std::cout << '\n';
return 0;
}
输出:
Comparing foo and bar lexicographically (foo<bar):
Using default comparison (operator<): true
Using mycomp as comparison object: false
3.变动性算法
3.1复制
copy():正向遍历序列
copy_back():逆向遍历序列
如果目标容器是空的,需要使用插入型迭代器InsertIterator
VS中的函数原型:
template<class _InIt,
class _OutIt> inline
_OutIt copy(_InIt _First, _InIt _Last,
_OutIt _Dest)
{ // copy [_First, _Last) to [_Dest, ...)
if (_First == _Last)
return (_Dest);
else
{ // worth copying, check then copy
_DEBUG_RANGE(_First, _Last);
_DEBUG_POINTER(_Dest);
return (_Copy_impl(_Unchecked(_First), _Unchecked(_Last),
_Dest, _Is_checked(_Dest)));
}
}
小小补充一下插入型迭代器知识:
function template
<iterator>
std::back_inserter
参考[1]http://www.cplusplus.com/reference/iterator/back_inserter/?kw=back_inserter
template <class Container>
back_insert_iterator<Container> back_inserter (Container& x);
迭代器功能:
Construct back insert iterator
Constructs a back-insert iterator that inserts new elements at the end of x.//在容器x的后面进行插入操作!
// back_inserter example
#include <iostream> // std::cout
#include <iterator> // std::back_inserter
#include <vector> // std::vector
#include <algorithm> // std::copy
int main () {
std::vector<int> foo,bar;
for (int i=1; i<=5; i++)
{ foo.push_back(i); bar.push_back(i*10); }
//foo={ 1 2 3 4 5} bar={10 20 30 40 50}
//在foo容器的后面插入bar
std::copy (bar.begin(),bar.end(),back_inserter(foo));
//foo={1 2 3 4 5 10 20 30 40 50}
std::cout << "foo contains:";
for ( std::vector<int>::iterator it = foo.begin(); it!= foo.end(); ++it )
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
输出:
foo contains: 1 2 3 4 5 10 20 30 40 50
/*插入型迭代器3种:要包含#include <iterator>
1.后插型:back_inserter()
2.前插型:front_inserter()
3.通用插入型(即插入位置可指定)inserter()*/
#include "stdafx.h"
#include<iostream>
#include<functional>
#include<algorithm>
#include<deque>
#include <iterator>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
/*插入型迭代器3种:要包含#include <iterator>
1.后插型:back_inserter()
2.前插型:front_inserter()
3.通用插入型(即插入位置可指定)inserter()*/
int dim[] = { 1, 2, 3, 4, 5, 6 };
deque<int> dq;
//deque<int>::back_inserter_iterator
//要包含#include <iterator>
copy(dim, dim + 6, back_inserter(dq));
copy(dq.begin(), dq.end(), ostream_iterator<int>(cout, ", "));
//流式迭代器ostream_iterator<int>(cout, ", ")
cout << endl;
//现在dq里面存了 { 1, 2, 3, 4, 5, 6 };元素
/*注意:front_inserter()只在deque和list容器中有实现。*/
front_inserter(dq) = 11;//得到{11, 1, 2, 3, 4, 5, 6 };
copy(dq.begin(), dq.end(), ostream_iterator<int>(cout, ", "));
cout << endl;
/*在dq前面再插入dq,注意是逆序的!*/
copy(dq.begin(), dq.end(), front_inserter(dq));
//dq={6, 5, 4, 3, 2, 1, 11, 11, 1, 2, 3, 4, 5, 6}
copy(dq.begin(), dq.end(), ostream_iterator<int>(cout, ", "));
cout << endl;
//通用插入迭代器inserter()
inserter(dq, dq.end()) = 33;
//dq={6, 5, 4, 3, 2, 1, 11, 11, 1, 2, 3, 4, 5, 6, 33}
copy(dq.begin(), dq.end(), ostream_iterator<int>(cout, ", "));
cout << endl;
system("pause");
return 0;
}
3.2变动性算法 转换transform:实现将源区间的元素复制到目标区间,复制和修改元素可一起完成!
transform():
参考:[1]http://www.cplusplus.com/reference/algorithm/transform/?kw=transform
unary operation(1)
template <class InputIterator, class OutputIterator, class UnaryOperation>
OutputIterator transform (InputIterator first1, InputIterator last1,
OutputIterator result, UnaryOperation op);//一元运算函数op
template <class InputIterator1, class InputIterator2,
class OutputIterator, class BinaryOperation>
OutputIterator transform (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, OutputIterator result,
BinaryOperation binary_op);//二元运算函数binary_op
Applies an operation sequentially to the elements of one (1) or two (2) ranges and stores the result in the range that begins at result.
(1) unary operation
Applies op to each of the elements in the range [first1,last1)
and stores the value returned by each operation in the range that begins at result.
(2) binary operation
Calls binary_op using each of the elements in the range [first1,last1)
as first argument, and the respective argument in the range that begins at first2 as second argument. The value returned by each call is stored in the range that begins at result.
// transform algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::transform
#include <vector> // std::vector
#include <functional> // std::plus
int op_increase (int i) { return ++i; }
int main () {
std::vector<int> foo;
std::vector<int> bar;
// set some values:
for (int i=1; i<6; i++)
foo.push_back (i*10); // foo: 10 20 30 40 50
bar.resize(foo.size()); // allocate space
std::transform (foo.begin(), foo.end(), bar.begin(), op_increase);
// bar: 11 21 31 41 51
// std::plus adds together its two arguments:
std::transform (foo.begin(), foo.end(), bar.begin(), foo.begin(), std::plus<int>());
// foo: 21 41 61 81 101
std::cout << "foo contains:";
for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
输出:
foo contains: 21 41 61 81 101
3.修改式(变动性)序列算法
3.3互换swap()
non-array (1)
template <class T> void swap (T& a, T& b)
noexcept (is_nothrow_move_constructible<T>::value && is_nothrow_move_assignable<T>::value);
array (2):
template <class T, size_t N> void swap(T (&a)[N], T (&b)[N])
noexcept (noexcept(swap(*a,*b)));
Exchanges the values of a and b.
// swap algorithm example (C++11)
#include <iostream> // std::cout
#include <utility> // std::swap
int main () {
int x=10, y=20; // x:10 y:20
std::swap(x,y); // x:20 y:10
int foo[4]; // foo: ? ? ? ?
int bar[] = {10,20,30,40}; // foo: ? ? ? ? bar: 10 20 30 40
std::swap(foo,bar); // foo: 10 20 30 40 bar: ? ? ? ?
std::cout << "foo contains:";
for (int i: foo) std::cout << ' ' << i;
std::cout << '\n';
return 0;
}
输出:
foo contains: 10 20 30 40
3.4赋值
用于给容器赋值:fill() 、fill_n()、generate()、generate_n()
向量vector的成员函数:assign():
3.5替换replace()
3.6逆转:reverse()和reverse_copy()
3.7旋转:rotate()和rotate_copy()
3.8排列:
排列:next_permutation()
重排(洗牌):random_shuffle()
将元素移动前面:划分:partition()
4.排序及相关操作:
4.1对全部元素排序:sort()和stable_sort()
4.2对局部元素排序:partical_sort()、partical_sort_copy()
4.3根据某个元素排序:nth_element() :类似于快速排序的一趟划分,枢轴元素归位!
4.4堆排序:make_heap()、push_heap()、pop_heap()、sort_heap()
4.5合并排序:
合并两个已序集合:merge()
两个已序集合的并集:union()
两个已序集合的交集:intersection()
两个已序集合的差集:defference()
连贯的已序集合的合并:inplace_merge()
4.6.搜索:
1.binary_search()
2.includes()
3.lower_bound()、upper_bound()、equal_range()
4.7删除算法:
1.remove()
2.remove_if()
3.remove_copy()
4.remove_copy_if()
5.unique()
6.unique_copy()
C++ STL算法