STL中算法锦集(三)
文章目录
- STL中算法锦集(三)
- 一、< algorithm >
- 1.std::find_if
- 2.std::find_if_not
- 3.std::for_each
- 4.std::generate
- 5.std::generate_n
- 6.std::includes
- 7.std::inplace_merge
- 8.std::is_heap
- 9.std::is_heap_until
- 10.std::is_partitioned
一、< algorithm >
1.std::find_if
template <class InputIterator, class UnaryPredicate>
InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred);
- InputIterator first:区间的开始
- InputIterator last:区间的结束
- UnaryPredicate pred:
自定义比较规则
,可以是函数指针或者仿函数对象、lambda表达式
- 作用:[first,last)区间内找满足pred条件的元素
- 返回值:
返回第一个满足pred条件的位置
- 实现:
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;
}
#include
#include
#include
bool IsOdd (int i) {
return ((i%2)==1);
}
int main () {
std::vector<int> myvector;
myvector.push_back(10);
myvector.push_back(25);
myvector.push_back(40);
myvector.push_back(55);
std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd);
std::cout << "The first odd value is " << *it << '\n';
return 0;
}
Output:
The first odd value is 25
2.std::find_if_not
template <class InputIterator, class UnaryPredicate>
InputIterator find_if_not (InputIterator first, InputIterator last, UnaryPredicate pred);
- InputIterator first:区间的开始
- InputIterator last:区间的结束
- UnaryPredicate pred:
自定义比较规则
,可以是函数指针或者仿函数对象、lambda表达式
- 作用:[first,last)区间找满足第一个不满足pred条件元素的位置
- 返回值:
返回第一个不满足pred条件元素的位置
- 实现:
template<class InputIterator, class UnaryPredicate>
InputIterator find_if_not (InputIterator first, InputIterator last, UnaryPredicate pred)
{
while (first!=last) {
if (!pred(*first)) return first;
++first;
}
return last;
}
#include
#include
#include
int main () {
std::array<int,5> foo = {1,2,3,4,5};
std::array<int,5>::iterator it =
std::find_if_not (foo.begin(), foo.end(), [](int i){return i%2;} );
std::cout << "The first even value is " << *it << '\n';
return 0;
}
Output:
The first even value is 2
3.std::for_each
template <class InputIterator, class Function>
Function for_each (InputIterator first, InputIterator last, Function fn);
- InputIterator first:区间的开始
- InputIterator last:区间的结束
- Function fn:
自定义动作
,可以是函数指针或者仿函数对象、lambda表达式
- 作用:
对[first,last)区间内的每个元素执行fn
- 返回值:返回每个元素执行的函数fn
- 实现:
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function fn)
{
while (first!=last) {
fn (*first);
++first;
}
return fn;
}
#include
#include
#include
void myfunction (int i) {
std::cout << ' ' << i;
}
struct myclass {
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';
std::cout << "myvector contains:";
for_each (myvector.begin(), myvector.end(), myobject);
std::cout << '\n';
return 0;
}
Output:
myvector contains: 10 20 30
myvector contains: 10 20 30
4.std::generate
template <class ForwardIterator, class Generator>
void generate (ForwardIterator first, ForwardIterator last, Generator gen);
- ForwardIterator first:区间的开始
- ForwardIterator last:区间的结束
- Generator gen:
自定义函数
,可以是函数指针或者仿函数对象、lambda表达式
- 作用:
把gen函数的执行结果赋值给[first,last)区间的每个位置
- 返回值:无返回值
- 实现:
template <class ForwardIterator, class Generator>
void generate ( ForwardIterator first, ForwardIterator last, Generator gen )
{
while (first != last) {
*first = gen();
++first;
}
}
#include
#include
#include
#include
#include
int RandomNumber () { return (std::rand()%100); }
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;
}
A possible output:
myvector contains: 57 87 76 66 85 54 17 15
myvector contains: 1 2 3 4 5 6 7 8
5.std::generate_n
template <class OutputIterator, class Size, class Generator>
void generate_n (OutputIterator first, Size n, Generator gen);
template <class OutputIterator, class Size, class Generator>
OutputIterator generate_n (OutputIterator first, Size n, Generator gen);
- OutputIterator first:区间的开始
- Size n:个数
- Generator gen:自定义函数
- 作用:把gen函数的返回值作为[first,last)区间前n个元素的值
- 返回值:
11返回最后一个成功赋值位置的下一个位置
- 实现:
template <class OutputIterator, class Size, class Generator>
void generate_n ( OutputIterator first, Size n, Generator gen )
{
while (n>0) {
*first = gen();
++first; --n;
}
}
#include
#include
int current = 0;
int UniqueNumber () { return ++current; }
int main () {
int myarray[9];
std::generate_n (myarray, 9, UniqueNumber);
std::cout << "myarray contains:";
for (int i=0; i<9; ++i)
std::cout << ' ' << myarray[i];
std::cout << '\n';
return 0;
}
A possible output:
myarray contains: 1 2 3 4 5 6 7 8 9
6.std::includes
template <class InputIterator1, class InputIterator2>
bool includes ( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2 );
template <class InputIterator1, class InputIterator2, class Compare>
bool includes ( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2, Compare comp );
- InputIterator1 first1:区间的开始
- InputIterator1 last1:区间的结束
- InputIterator2 first2:区间的开始
- InputIterator2 last2:区间的结束
- Compare comp:自定义比较规则
需要排序
- 作用:
[first1,last1)区间是否全部包含[first2,last2)中的所有元素
- 返回值:是则返回true,反之返回false
- 实现:
template <class InputIterator1, class InputIterator2>
bool includes (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2)
{
while (first2!=last2) {
if ( (first1==last1) || (*first2 < *first1) ) return false;
if (!(*first1 < *first2)) ++first2;
++first1;
}
return true;
}
#include
#include
bool myfunction (int i, int j) { return i<j; }
int main () {
int container[] = {5,10,15,20,25,30,35,40,45,50};
int continent[] = {40,30,20,10};
std::sort (container,container+10);
std::sort (continent,continent+4);
if ( std::includes(container,container+10,continent,continent+4) )
std::cout << "container includes continent!\n";
if ( std::includes(container,container+10,continent,continent+4, myfunction) )
std::cout << "container includes continent!\n";
return 0;
}
Output:
container includes continent!
container includes continent!
7.std::inplace_merge
template <class BidirectionalIterator>
void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle,
BidirectionalIterator last);
template <class BidirectionalIterator, class Compare>
void inplace_merge (BidirectionalIterator first, BidirectionalIterator middle,
BidirectionalIterator last, Compare comp);
- BidirectionalIterator first:区间的开始
- BidirectionalIterator middle:区间的中间位置,即分割线
- BidirectionalIterator last:区间的结束
- Compare comp:自定义比较规则
[first,middle)区间和[middle,last)区间都需要有序
,功能类似与排序,只不过是两个有序小区间合并成一个大的有序区间
- 作用:
把[first,middle)区间和[middle,last)区间合并并排序
- 返回值:无返回值
- 案例:
#include
#include
#include
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;
}
Output:
The resulting vector contains: 5 10 10 15 20 20 25 30 40 50
8.std::is_heap
template <class RandomAccessIterator>
bool is_heap (RandomAccessIterator first, RandomAccessIterator last);
template <class RandomAccessIterator, class Compare>
bool is_heap (RandomAccessIterator first, RandomAccessIterator last,
Compare comp);
- RandomAccessIterator first:区间的开始
- RandomAccessIterator last:区间的结束
- Compare comp:
自定义比较规则
,可以是函数指针或者仿函数对象、lambda表达式
- 作用:
判断[first,last)区间元素是否构成一个堆
- 返回值:true代表构成一个堆,反之不构成堆
- 案例:
#include
#include
#include
int main () {
std::vector<int> foo {9,5,2,6,4,1,3,8,7};
if (!std::is_heap(foo.begin(),foo.end()))
std::make_heap(foo.begin(),foo.end());
std::cout << "Popping out elements:";
while (!foo.empty()) {
std::pop_heap(foo.begin(),foo.end());
std::cout << ' ' << foo.back();
foo.pop_back();
}
std::cout << '\n';
return 0;
}
Output:
Popping out elements: 9 8 7 6 5 4 3 2 1
9.std::is_heap_until
template <class RandomAccessIterator>
RandomAccessIterator is_heap_until (RandomAccessIterator first,
RandomAccessIterator last);
template <class RandomAccessIterator, class Compare>
RandomAccessIterator is_heap_until (RandomAccessIterator first,
RandomAccessIterator last
Compare comp);
- RandomAccessIterator first:区间的开始
- RandomAccessIterator last:区间的结束
- Compare comp:
自定义比较规则
,可以是函数指针或者仿函数对象、lambda表达式
- 作用:
求[first,last)区间内第一个导致不满足堆特性的元素位置
- 返回值:返回第一个导致不满足堆特性的元素位置
- 案例:
#include
#include
#include
int main () {
std::vector<int> foo {2,6,9,3,8,4,5,1,7};
std::sort(foo.begin(),foo.end());
std::reverse(foo.begin(),foo.end());
auto last = std::is_heap_until (foo.begin(),foo.end());
std::cout << "The " << (last - foo.begin()) << " first elements are a valid heap:";
for (auto it=foo.begin(); it!=last; ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
Most implementations consider a range sorted in reverse order a valid heap:
Possible output:
The 9 first elements are a valid heap: 9 8 7 6 5 4 3 2 1
10.std::is_partitioned
template <class InputIterator, class UnaryPredicate>
bool is_partitioned (InputIterator first, InputIterator last, UnaryPredicate pred);
- InputIterator first:区间的开始
- InputIterator last:区间的结束
- UnaryPredicate pred:
自定义比较规则
,可以是函数指针或者仿函数对象、lambda表达式
- 作用:
判断[first,last)区间内的所有满足pred条件的元素是否都在开始位置,且一旦出现不满足pred的元素后,后面不能再出现满足pred条件的元素
- 返回值:满足条件返回true,反之返回false
- 实现:
template <class InputIterator, class UnaryPredicate>
bool is_partitioned (InputIterator first, InputIterator last, UnaryPredicate pred)
{
while (first!=last && pred(*first)) {
++first;
}
while (first!=last) {
if (pred(*first)) return false;
++first;
}
return true;
}
#include
#include
#include
bool IsOdd (int i) { return (i%2)==1; }
int main () {
std::array<int,7> foo {1,2,3,4,5,6,7};
std::cout << "foo:"; for (int& x:foo) std::cout << ' ' << x;
if ( std::is_partitioned(foo.begin(),foo.end(),IsOdd) )
std::cout << " (partitioned)\n";
else
std::cout << " (not partitioned)\n";
std::partition (foo.begin(),foo.end(),IsOdd);
std::cout << "foo:"; for (int& x:foo) std::cout << ' ' << x;
if ( std::is_partitioned(foo.begin(),foo.end(),IsOdd) )
std::cout << " (partitioned)\n";
else
std::cout << " (not partitioned)\n";
return 0;
}
Possible output:
foo: 1 2 3 4 5 6 7 (not partitioned)
foo: 1 7 3 5 4 6 2 (partitioned)