注:C++ STL算法部分主要直接来阅读STL源码库,源码来源于http://www.cplusplus.com/网站。
《C++标准库》侯捷,华中科技大学出版社一书是在2001年出版的,之前的例程中不涉及C++11新标准,最新的源码库中有相当部分的算法采用了新标准。
所以在原来的 g++ (GCC) 3.2.2 20030222 上编译无法通过。为了方便起见,就选用dev-c++来进行编译。编译器选项选择GUN C++11。
Dev-C++配置如下:
在STL中非改变序列性算法包含有:
下面以此来测试上述算法:
1、all_of
all_of的在STL中源码如下所示,它是属于C++11新标准中的一个算法函数
template<class InputIterator, class UnaryPredicate>
bool all_of (InputIterator first, InputIterator last, UnaryPredicate pred)
{
while (first != last)
{
if (!pred(*first))
return false;
++first;
}
return true;
}
all_of的功能:1、返回 true :输入的序列中的每个元素都使pred仿函数返回true
或者输入的是一个空的序列,即:first == last
2、返回 false:输入的序列中任意一个元素使pred仿函数返回false
2、any_of
any_of的在STL中源码如下所示,它是属于C++11新标准中的一个算法函数,
any_of和上述的all_of很相似,它的功能是判别输入的序列中是否有元素满足判别条件。
template<class InputIterator, class UnaryPredicate>
bool any_of (InputIterator first, InputIterator last, UnaryPredicate pred)
{
while (first!=last) {
if (pred(*first)) return true;
++first;
}
return false;
}
3、none_of
none_of和all_of的功能则正好相反template<class InputIterator, class UnaryPredicate>
bool none_of (InputIterator first, InputIterator last, UnaryPredicate pred)
{
while (first!=last) {
if (pred(*first)) return false;
++first;
}
return true;
}
example:
上述三个函数举例比较如下:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class Func
{
private:
int vl; //类对象的内部状态
public:
Func(int init) : vl(init)
{
}
bool operator() (int elem)
{
if(elem < vl)
return true;
else
return false;
}
};
int main()
{
vector<int> col1;
for(int i=0; i<=9; ++i)
{
col1.push_back(i);
}
bool rt_all_of1 = all_of(col1.begin(), col1.end(), Func(10)); //序列中所有值小于10
bool rt_all_of2 = all_of(col1.begin(), col1.end(), Func(5)); //序列中所有值小于5
bool rt_any_of1 = any_of(col1.begin(), col1.end(), Func(2)); //序列中存在值小于2
bool rt_any_of2 = any_of(col1.begin(), col1.end(), Func(-1)); //序列中存在值小于-1
bool rt_none_of1 = none_of(col1.begin(), col1.end(), Func(-1)); //序列中没有值小于-1
bool rt_none_of2 = none_of(col1.begin(), col1.end(), Func(1)); //序列中没有值小于1
cout<< "all_of: " << rt_all_of1 << '\t' << rt_all_of2 << endl
<< "any_of: " << rt_any_of1 << '\t' << rt_any_of2 << endl
<< "none_of: " << rt_none_of1 << '\t' << rt_none_of2 << endl;
return 0 ;
}
运行结果:
4、for_each
for_each在前面已经用到过多次,它是对输入序列中的每一个元素执行fn操作。template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function fn)
{
while (first!=last) {
fn (*first);
++first;
}
return fn; // or, since C++11: return move(fn);
}
5、find
find的功能是查找输入序列是否有值val的出现,若有,则返回查找到的第一个的迭代器。若序列中不存在则返回序列最后一个元素的迭代器。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;
}
6、find_if
find_if可以说是find的升级版,它是查找序列中元素满足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;
}
7、find_if_not
find_if_not和find_if查找的要求是刚好相反的,它是查找序列中元素不满足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;
}
8、adjacent_find
查找序列中相邻相等的元素,并返回相等的首元素位置(迭代器),否则返回最后一个元素template <class ForwardIterator>
ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last)
{
if (first != last)
{
ForwardIterator next=first; ++next;
while (next != last) {
if (*first == *next) // or: if (pred(*first,*next)), for version (2)
return first;
++first; ++next;
}
}
return last;
}
9、count
返回序列中等于带入值val的元素个数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;
}
10、count_if
返回序列中满足pred的元素个数template <class InputIterator, class UnaryPredicate>
typename iterator_traits<InputIterator>::difference_type
count_if (InputIterator first, InputIterator last, UnaryPredicate pred)
{
typename iterator_traits<InputIterator>::difference_type ret = 0;
while (first!=last) {
if (pred(*first)) ++ret;
++first;
}
return ret;
}
11、mismatch
返回两个序列中不相等的首元素对template <class InputIterator1, class InputIterator2>
pair<InputIterator1, InputIterator2>
mismatch (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2 )
{
while ( (first1!=last1) && (*first1==*first2) ) // or: pred(*first1,*first2), for version 2
{ ++first1; ++first2; }
return std::make_pair(first1,first2);
}
12、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;
}
13、is_permutation
比较序列first1 - last1区间元素是否和first2开始的区间元素都存在template <class InputIterator1, class InputIterator2>
bool is_permutation (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2)
{
std::tie (first1,first2) = std::mismatch (first1,last1,first2);
if (first1==last1) return true;
InputIterator2 last2 = first2; std::advance (last2,std::distance(first1,last1));
for (InputIterator1 it1=first1; it1!=last1; ++it1) {
if (std::find(first1,it1,*it1)==it1) {
auto n = std::count (first2,last2,*it1);
if (n==0 || std::count (it1,last1,*it1)!=n) return false;
}
}
return true;
}
14、search
查找序列first1 - last1在序列first2 - last2中是否存在,存在则返回出现位置的迭代器。template<class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 search ( ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2)
{
if (first2==last2) return first1; // specified in C++11
while (first1!=last1)
{
ForwardIterator1 it1 = first1;
ForwardIterator2 it2 = first2;
while (*it1==*it2) { // or: while (pred(*it1,*it2)) for version 2
++it1; ++it2;
if (it2==last2) return first1;
if (it1==last1) return last1;
}
++first1;
}
return last1;
}
15、search_n
template<class ForwardIterator, class Size, class T>
ForwardIterator search_n (ForwardIterator first, ForwardIterator last,
Size count, const T& val)
{
ForwardIterator it, limit;
Size i;
limit=first; std::advance(limit,std::distance(first,last)-count);
while (first!=limit)
{
it = first; i=0;
while (*it==val) // or: while (pred(*it,val)) for the pred version
{ ++it; if (++i==count) return first; }
++first;
}
return last;
}