您的位置:首页 > 编程语言

STL与泛型编程<十八>:STL算法之非变动性算法(Nonmodifying algorithm)

2016-04-07 20:22 399 查看

1.元素计数(count和count_if)

count声明:

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;
}
/*
可知返回值型别是difference_type,表现迭代器间距的型别
*/


count_if声明如下

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;
}


使用如下

int val[] = {1,2,3,4,5,6};
vector<int> col(val,val+6);
int cnt = count(col.begin(),col.end(),4); //1
cnt = count_if(col.begin(),col.end(),bind2nd(greater<int>(),4));//3


2.最小值和最大值(max_element)

max_element声明

template <class ForwardIterator>
ForwardIterator max_element (ForwardIterator first, ForwardIterator last);//默认以operator < 进行比较

template <class ForwardIterator, class Compare>
ForwardIterator max_element (ForwardIterator first, ForwardIterator last, Compare comp);


等效于

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

while (++first!=last)
{
if (*largest<*first)    // or: if (comp(*largest,*first)) for version (2)
largest=first;
}
return largest;
}


使用如下

#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;
}


3.搜寻元素(find和find_if)

1.搜寻第一个匹配元素

find声明如下

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;
}


find_if声明如下

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;
}


使用如下

int val[] = {1,2,3,45,6};
vector<int> col(val,val+6);
vector<int>::iterator pos = find(col.begin(),col.end(),45);
if (pos != col.end())
{
//found!
}
pos = find_if(col.begin(),col.end(),bind2nd(greater<int>(),2));


2.搜寻前n个连续匹配值(search_n)

search_n的声明:

template <class ForwardIterator, class Size, class T>
ForwardIterator search_n (ForwardIterator first, ForwardIterator last, Size count, const T& val); //返回第一组“连续count个元素全等于value”的元素位置的第一个元素

template <class ForwardIterator, class Size, class T, class BinaryPredicate>
ForwardIterator search_n ( ForwardIterator first, ForwardIterator last, Size count, const T& val, BinaryPredicate pred );// 寻找pred(elem,val)为true的,返回意义同上


等效于

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); //first只可能到limit位置

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;  //not found ,return last
}


例子

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

bool mypredicate (int i, int j) {
return (i==j);
}

int main ()
{
int myints[]={10,20,30,30,20,10,10,20};
std::vector<int> myvector (myints,myints+8);

std::vector<int>::iterator it;

// using default comparison:
it = std::search_n (myvector.begin(), myvector.end(), 2, 30);

if (it!=myvector.end())
std::cout << "two 30s found at position " << (it-myvector.begin()) << '\n'; //2
else
std::cout << "match not found\n";

// using predicate comparison:
it = std::search_n (myvector.begin(), myvector.end(), 2, 10, mypredicate);

if (it!=myvector.end())
std::cout << "two 10s found at position " << int(it-myvector.begin()) << '\n'; // 5
else
std::cout << "match not found\n";

return 0;
}


关于search_n的第二种形式,请看以下调用

pos = seach_n(col.begin(),col.end(),4,3,greater<int>());//以这种方法来搜寻元素和以往的STL算法有些不同,以往的可能如下
pos = seach_n_if(col.begin(),col.end(),4,bind2nd(greater<int>(),3));


3.搜寻第一个子区间(search)

search声明

template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2);

template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);

/*
两种形式都返回区间[first1,last1)内和区间[first2,last2)完全吻合的第一个自区间内的第一个元素位置,如果没有找到都返回last1
*/


其等效于

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;
}


例子如下

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

bool mypredicate (int i, int j) {
return (i==j);
}

int main (void)
{
std::vector<int> haystack;

// set some values:        haystack: 10 20 30 40 50 60 70 80 90
for (int i=1; i<10; i++)
haystack.push_back(i*10);

// using default comparison:
int needle1[] = {40,50,60,70};
std::vector<int>::iterator it;
it = std::search (haystack.begin(), haystack.end(), needle1, needle1+4);

if (it!=haystack.end())
std::cout << "needle1 found at position " << (it-haystack.begin()) << '\n'; //3
else
std::cout << "needle1 not found\n";

// using predicate comparison:
int needle2[] = {20,30,50};
it = std::search (haystack.begin(), haystack.end(), needle2, needle2+3, mypredicate);

if (it!=haystack.end())
std::cout << "needle2 found at position " << (it-haystack.begin()) << '\n';
else
std::cout << "needle2 not found\n";//needle2 not found

return 0;
}


4.搜寻最后一个子区间(find_end)

find_end声明如下

template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2);

template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);
/*
两种形式都返回[first1,last1)之中和区间[first2,last2)完全吻合的最后一个子区间的第一个元素位置,否则返回last1
*/


等效于

template<class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2)
{
if (first2==last2) return last1;  // specified in C++11

ForwardIterator1 ret = last1;

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) { ret=first1; break; }
if (it1==last1) return ret;
}
++first1;
}
return ret;
}


例子如下

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

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

int main () {
int myints[] = {1,2,3,4,5,1,2,3,4,5};
std::vector<int> haystack (myints,myints+10);

int needle1[] = {1,2,3};

// using default comparison:
std::vector<int>::iterator it;
it = std::find_end (haystack.begin(), haystack.end(), needle1, needle1+3);

if (it!=haystack.end())
std::cout << "needle1 last found at position " << (it-haystack.begin()) << '\n'; // 5

int needle2[] = {4,5,1};

// using predicate comparison:
it = std::find_end (haystack.begin(), haystack.end(), needle2, needle2+3, myfunction);

if (it!=haystack.end())
std::cout << "needle2 last found at position " << (it-haystack.begin()) << '\n';// 3

return 0;
}


5.搜寻某些元素第一次出现的地点(find_first_of)

find_first_of 声明

template <class ForwardIterator1, class ForwardIterator2>
ForwardIterator1 find_first_of (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2);

template <class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
ForwardIterator1 find_first_of (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred);//pred(*it1,*it2),其中it1是
/*
返回第一个既在[first1,end1)也在[first2,end2)出现的元素的位置(在[first1,end1)总的位置),失败返回last1
*/


其等效于

template<class InputIterator, class ForwardIterator>
InputIterator find_first_of ( InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2)
{
while (first1!=last1)
{
for (ForwardIterator it=first2; it!=last2; ++it)
{
if (*it==*first1)          // or: if (pred(*first1,*it)) for version (2)
return first1;
}
++first1;
}
return last1;
}


例子如下

// find_first_of example
#include <iostream>     // std::cout
#include <algorithm>    // std::find_first_of
#include <vector>       // std::vector
#include <cctype>       // std::tolower

bool comp_case_insensitive (char c1, char c2) {
return (std::tolower(c1)==std::tolower(c2));
}

int main ()
{
int mychars[] = {'a','b','c','A','B','C'};
std::vector<char> haystack (mychars,mychars+6);
std::vector<char>::iterator it;

int needle[] = {'A','B','C'};

// using default comparison:
it = find_first_of (haystack.begin(), haystack.end(), needle, needle+3);

if (it!=haystack.end())
std::cout << "The first match is: " << *it << '\n'; //A

// using predicate comparison:
it = find_first_of (haystack.begin(), haystack.end(),
needle, needle+3, comp_case_insensitive);

if (it!=haystack.end())
std::cout << "The first match is: " << *it << '\n';//a

return 0;
}


6.搜寻两个连续相等的元素(adjacent_find)

adjacent_find声明如下

template <class ForwardIterator>
ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last);

template <class ForwardIterator, class BinaryPredicate>
ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last, BinaryPredicate pred);//pred(*it,*(it+1))

/*
返回第一个“两个连续相等的元素”中的第一个元素位置,失败返回last
*/


等效于

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;
}


使用如下

int val[] = {1,2,3,100,100,5};
vector<int> col(val,val+6);
vector<int>::iterator pos;
pos = adjacent_find(col.begin(),col.end()); //返回第一个100的位置
pos = adjacent_find(col.begin(),col.end(),greater<int>()); //回第二个100的位置


区间的比较

1.检验相等性(equal)

equal声明

template <class InputIterator1, class InputIterator2>
bool equal (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);//判断区间[first1,last1)内的元素是否都和“以first2开头的区间”的元素都相等

template <class InputIterator1, class InputIterator2, class BinaryPredicate>
bool equal (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred);//pred(*it1,*it2)


等效于

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;
}


例子如下

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

bool mypredicate (int i, int j) {
return (i==j);
}

int main ()
{
int myints[] = {20,40,60,80,100};               //   myints: 20 40 60 80 100
std::vector<int>myvector (myints,myints+5);     // myvector: 20 40 60 80 100

// using default comparison:
if ( std::equal (myvector.begin(), myvector.end(), myints) )
std::cout << "The contents of both sequences are equal.\n"; //打印这行
else
std::cout << "The contents of both sequences differ.\n";

myvector[3]=81;                                 // myvector: 20 40 60 81 100

// using predicate comparison:
if ( std::equal (myvector.begin(), myvector.end(), myints, mypredicate) )
std::cout << "The contents of both sequences are equal.\n";
else
std::cout << "The contents of both sequences differ.\n";// 打印这行

return 0;
}


2. 搜寻第一处不同点(mismatch)

声明如下

template <class InputIterator1, class InputIterator2>
pair<InputIterator1, InputIterator2> //返回值
mismatch (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);

template <class InputIterator1, class InputIterator2, class BinaryPredicate>
pair<InputIterator1, InputIterator2>
mismatch (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred);//pred(*it1,*it2)
/*
返回区间[first1,end1)和"以first2开头区间"之中第一组两两相异的对应元素
*/


等效于

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);
}


例子如下

// mismatch algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::mismatch
#include <vector>       // std::vector
#include <utility>      // std::pair

bool mypredicate (int i, int j) {
return (i==j);
}

int main () {
std::vector<int> myvector;
for (int i=1; i<6; i++) myvector.push_back (i*10); // myvector: 10 20 30 40 50

int myints[] = {10,20,80,320,1024};                //   myints: 10 20 80 320 1024

std::pair<std::vector<int>::iterator,int*> mypair;

// using default comparison:
mypair = std::mismatch (myvector.begin(), myvector.end(), myints);
std::cout << "First mismatching elements: " << *mypair.first; // 30
std::cout << " and " << *mypair.second << '\n';// 80

++mypair.first;
++mypair.second;

// using predicate comparison:
mypair = std::mismatch (mypair.first, myvector.end(), mypair.second, mypredicate);
std::cout << "Second mismatching elements: " << *mypair.first;// 40
std::cout << " and " << *mypair.second << '\n';// 320

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: