STL algorithm/numeric 函数总结

algorithm

官方文档

https://www.cplusplus.com/reference/algorithm/
很多函数其实用不到,只有少部分用的很多,其实官方文档写的很清楚也有例子,这里总结一下个人认为比较常用的函数

count

计算给定迭代器区间内与元素相等的个数

int count (InputIterator first, InputIterator last, const T& val);

int myints[] = {10,20,30,30,20,10,10,20};   // 8 elements
int mycount = std::count (myints, myints+8, 10);
std::cout << "10 appears " << mycount << " times.\n";
//10 appears 3 times.

fill

给定迭代器区间使用给定值填充

void fill (ForwardIterator first, ForwardIterator last, const T& val);

generate

以指定动作运算结果填充特定范围内的元素内容,类似python里的列表生成式的作用。第三个参数必须是lambda函数或者函数,或者函数对象,即均有重载operator()()的类对象。

 void generate (ForwardIterator first, ForwardIterator last, Generator gen);

官方实例

// generate algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::generate
#include <vector>       // std::vector
#include <ctime>        // std::time
#include <cstdlib>      // std::rand, std::srand

// function generator:
int RandomNumber () { return (std::rand()%100); }

// class generator:
struct c_unique {
  int current;
  c_unique() {current=0;}
  int operator()() {return ++current;}
} UniqueNumber;

int main () {
  std::srand ( unsigned ( std::time(0) ) );

  std::vector<int> myvector (8);

  std::generate (myvector.begin(), myvector.end(), RandomNumber);

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  std::generate (myvector.begin(), myvector.end(), UniqueNumber);

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';
 
  return 0;
}

generate_n

与generate类似,不过第二个参数不为迭代器末尾,为生成数量。

void generate_n (OutputIterator first, Size n, Generator gen);

reverse

给定区间反转,是原内存进行反转,没有返回值。

void reverse (BidirectionalIterator first, BidirectionalIterator last);

shuffle

random_shuffle 对给定区间进行随机打乱,可传入自定义随机函数。
shuffle需要传入随机数引擎。
random_shuffle 的定义等效如下。可以看到gen函数应是生成一个在0-i之间的随机数。

 void random_shuffle (RandomAccessIterator first, RandomAccessIterator last,
                       RandomNumberGenerator& gen)
{
  iterator_traits<RandomAccessIterator>::difference_type i, n;
  n = (last-first);
  for (i=n-1; i>0; --i) {
    swap (first[i],first[gen(i+1)]);
  }
void random_shuffle (RandomAccessIterator first, RandomAccessIterator last);
void random_shuffle (RandomAccessIterator first, RandomAccessIterator last,RandomNumberGenerator&& gen);
void shuffle (RandomAccessIterator first, RandomAccessIterator last, UniformRandomNumberGenerator&& g);

实例

// random_shuffle example
#include <iostream>     // std::cout
#include <algorithm>    // std::random_shuffle
#include <vector>       // std::vector
#include <ctime>        // std::time
#include <cstdlib>      // std::rand, std::srand

// random generator function:
int myrandom (int i) { return std::rand()%i;}

int main () {
  std::srand ( unsigned ( std::time(0) ) );
  std::vector<int> myvector;

  // set some values:
  for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9

  // using built-in random generator:
  std::random_shuffle ( myvector.begin(), myvector.end() );

  // using myrandom:
  std::random_shuffle ( myvector.begin(), myvector.end(), myrandom);

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;

  std::cout << '\n';

  return 0;
}

partition

partition算法作用为对指定范围内元素重新排序,使用输入的函数,把结果为true的元素放在结果为false的元素之前,pred为自定义函数,返回值为正向迭代器,其指向的是两部分数据的分界位置,更确切地说,指向的是第二组数据中的第 1 个元素。

ForwardIterator partition (ForwardIterator first,
                           ForwardIterator last, UnaryPredicate pred);

实例

#include <iostream>     // std::cout
#include <algorithm>    // std::partition
#include <vector>       // std::vector

bool IsOdd (int i) { return (i%2)==1; }

int main () {
  std::vector<int> myvector;

  // set some values:
  for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9

  std::vector<int>::iterator bound;
  bound = std::partition (myvector.begin(), myvector.end(), IsOdd);

  // print out content:
  std::cout << "odd elements:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=bound; ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  std::cout << "even elements:";
  for (std::vector<int>::iterator it=bound; it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

sort

对指定区间排序,默认升序,可自定比较函数。同样的三种方式。

// sort algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::sort
#include <vector>       // std::vector

bool myfunction(int i, int j) { return (i<j); }

struct myclass {
	bool operator() (int i, int j) { return (i<j); }
} myobject;

int main() {
	int myints[] = { 32,71,12,45,26,80,53,33 };
	std::vector<int> myvector(myints, myints + 8);               // 32 71 12 45 26 80 53 33
	std::sort(myvector.begin(), myvector.end(), [](const int &a, const int &b) {return a < b; }); // 12 32 45 71(26 33 53 80)
	std::cout << "lambda:myvector contains:";
	for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
		std::cout << ' ' << *it;
	std::cout << '\n';

																 // using function as comp
	std::sort(myvector.begin(), myvector.end(), myfunction); // 12 32 45 71(26 33 53 80)
	std::cout << "myfunction:myvector contains:";
	for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
		std::cout << ' ' << *it;
	std::cout << '\n';
																 // using object as comp
	std::sort(myvector.begin(), myvector.end(), myobject);     //(12 26 32 33 45 53 71 80)

															   // print out content:
	std::cout << "myobject:myvector contains:";
	for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
		std::cout << ' ' << *it;
	std::cout << '\n';

	return 0;
}


stable_sort

与sort使用方法一致,但会保证前后顺序。
sort是快速排序实现,因此是不稳定的;stable_sort是归并排序实现,因此是稳定的

lower_bound

二分查找非递减序列内第一个大于或等于某个元素的位置。
可自定义比较函数,函数的返回的值指示是否认为第一个参数在第二个参数之前。

ForwardIterator lower_bound (ForwardIterator first,ForwardIterator last, const T& val);
ForwardIterator lower_bound (ForwardIterator first,ForwardIterator last, const T& val, Compare comp);

定义如下:

  ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val)
{
  ForwardIterator it;
  iterator_traits<ForwardIterator>::difference_type count, step;
  count = distance(first,last);
  while (count>0)
  {
    it = first; step=count/2; advance (it,step);
    if (comp(*it,val)) {                 
      first=++it;
      count-=step+1;
    }
    else count=step;
  }
  return first;
}

一般默认comp(it,val)为<比较,所以由定义我们看出lower是找出第一个使it和val的比较函数为假的位置。

upper_bound

查找非递减序列内第一个大于某个元素的位置。与lower_bound用法一致。定义如下:

 ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val)
{
  ForwardIterator it;
  iterator_traits<ForwardIterator>::difference_type count, step;
  count = std::distance(first,last);
  while (count>0)
  {
    it = first; step=count/2; std::advance (it,step);
    if (!comp(val,*it)) { 
    	first=++it; 
    	count-=step+1;  
    }
    else count=step;
  }
  return first;
}

upper比较复杂,因为这里传入cmp的参数是反顺序的。自行理解吧

merge

归并排序,可自定义比较函数,但自定义比较函数使用时需要归并的两个数组必须按cmp函数已经排好序。

OutputIterator merge (InputIterator1 first1, InputIterator1 last1,InputIterator2 first2, InputIterator2 last2,OutputIterator result);
OutputIterator merge (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,OutputIterator result, Compare comp);
// merge algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::merge, std::sort
#include <vector>       // std::vector
#include <functional>
bool myfunction(const int &i, const int &j) { return (i>j); }
int main() {
	int first[] = { 5,10,15,20,25 };
	int second[] = { 50,40,30,20,10 };
	std::vector<int> v(10);

	std::sort(first, first + 5, myfunction);
	std::sort(second, second + 5, myfunction);
	std::merge(first, first + 5, second, second + 5, v.begin(), myfunction);

	std::cout << "The resulting vector contains:";
	for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it)
		std::cout << ' ' << *it;
	std::cout << '\n';

	return 0;
}

inplace_merge

对原数组就地排序,需要传入三个位置分成两个区间,区间归并前需要安装cmp进行排序

void inplace_merge (BidirectionalIterator first,BidirectionalIterator middle,BidirectionalIterator last);
void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle,BidirectionalIterator last, Compare comp);

实例

// inplace_merge example
#include <iostream>     // std::cout
#include <algorithm>    // std::inplace_merge, std::sort, std::copy
#include <vector>       // std::vector

int main () {
  int first[] = {5,10,15,20,25};
  int second[] = {50,40,30,20,10};
  std::vector<int> v(10);
  std::vector<int>::iterator it;

  std::sort (first,first+5);
  std::sort (second,second+5);

  it=std::copy (first, first+5, v.begin());
     std::copy (second,second+5,it);

  std::inplace_merge (v.begin(),v.begin()+5,v.end());

  std::cout << "The resulting vector contains:";
  for (it=v.begin(); it!=v.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

min_element

查找最小元素,返回最小位置迭代器。也可自定义比较函数。

ForwardIterator min_element (ForwardIterator first, ForwardIterator last);
ForwardIterator min_element (ForwardIterator first, ForwardIterator last,Compare comp);

定义:

template <class ForwardIterator>
  ForwardIterator min_element ( ForwardIterator first, ForwardIterator last )
{
  if (first==last) return last;
  ForwardIterator smallest = first;

  while (++first!=last)
    if (comp(*first,*smallest)) smallest=first;
  return smallest;
}
// 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

max_element

一样。但比较部分为(comp(*largest,*first))。

template <class ForwardIterator>
  ForwardIterator max_element ( ForwardIterator first, ForwardIterator last )
{
  if (first==last) return last;
  ForwardIterator largest = first;

  while (++first!=last)
    if (comp(*largest,*first))   largest=first;
  return largest;
}

next_permutation

计算序列全排列的函数,可自定义比较函数。
当当前序列不存在下一个排列时,函数返回false,否则返回true

bool next_permutation (BidirectionalIterator first,
                         BidirectionalIterator last);
bool next_permutation (BidirectionalIterator first,
                         BidirectionalIterator last, Compare comp);
// next_permutation example
#include <iostream>     // std::cout
#include <algorithm>    // std::next_permutation, std::sort
bool myfunction(const int &i, const int &j) { return (i>j); }

int main() {
	int myints[] = {3,2,1 };

	//std::sort(myints, myints + 3);

	std::cout << "The 3! possible permutations with 3 elements:\n";
	do {
		std::cout << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '\n';
	} while (std::next_permutation(myints, myints + 3, myfunction));

	std::cout << "After loop: " << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '\n';

	return 0;
}

numeric

accumulate

T accumulate (InputIterator first, InputIterator last, T init);
T accumulate (InputIterator first, InputIterator last, T init,BinaryOperation binary_op);

定义如下:

template <class InputIterator, class T>
   T accumulate (InputIterator first, InputIterator last, T init)
{
  while (first!=last) {
    init=binary_op(init,*first);  //默认累加
    ++first;
  }
  return init;
}

使用实例

// accumulate example
#include <iostream>     // std::cout
#include <functional>   // std::minus
#include <numeric>      // std::accumulate

int myfunction (int x, int y) {return x+2*y;}
struct myclass {
	int operator()(int x, int y) {return x+3*y;}
} myobject;

int main () {
  int init = 100;
  int numbers[] = {10,20,30};

  std::cout << "using default accumulate: ";
  std::cout << std::accumulate(numbers,numbers+3,init);
  std::cout << '\n';

  std::cout << "using functional's minus: ";
  std::cout << std::accumulate (numbers, numbers+3, init, std::minus<int>());
  std::cout << '\n';

  std::cout << "using custom function: ";
  std::cout << std::accumulate (numbers, numbers+3, init, myfunction);
  std::cout << '\n';

  std::cout << "using custom object: ";
  std::cout << std::accumulate (numbers, numbers+3, init, myobject);
  std::cout << '\n';

  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值