STL中的算法

目录

1.STL算法库

2.非修改式序列算法

3.修改式序列算法

4.排序和相关算法

5.通用数值算法

 

0。参观一下STL有些什么算法:

<algorithm>

 

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搜索算法

  1. find()

  2. find_if()

  3. find_first_of()

  4. find_end()

  5. search()

  6. search_n()

  7. adjacent_find()

 

 

2.5区间比较算法

  1. equal()

  2. mismatch()

  3. 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).

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算法

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值