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; }
相关文章推荐
- 《C#高级编程》
- js 编码、解码与asp.net 编码、解码
- 「学习笔记」4.7代码学习
- java 日期处理大全
- lua的Metatables和Metamethods
- C++单向链表之删除节点
- windows下使用eclipse远程编写hadoop配置
- c语言的知识与能力自评
- Java字节流和字符流
- Google Chrome源码剖析【五】:插件模型
- C语言参数传递
- Feather R语言和Python交互式硬盘存储格式
- Google Chrome源码剖析【三】:进程模型
- C++服务器(六):socket 异步模型与select 的实现
- Java定时任务(2)
- UVA_544_Heavy Cargo
- C++实验三--个人所得税计算器
- Google Chrome源码剖析【二】:进程通信
- simulink仿真错误:MATLAB Function Interface Error
- 简单Python3爬虫程序(1)简单架构:队列、集合、正则