算法
adjacent_find count count_if find find_if find_end for_each generate generate_n includes max_element merge min_element partition remove remove remove_copy remove_if remove_copy_if replace replace_copy replace_if replace_copy_if reverse reverse_copy rotate rotate_copy search search_n swap_ranges transform unique unique_copy
adjacent_find
找出第一組滿足條件的相鄰元素,版本一是指兩個(gè)元素相等;版本二允許用戶指定一個(gè)二元運(yùn)算,兩個(gè)操作數(shù)分別是相鄰的第一元素和第二元素
#include <iostream>
#include <vector>template <class ForwardIterator>
ForwardIterator adjacent_find(ForwardIterator first,ForwardIterator last){if (first != last){ForwardIterator next = first; ++next;while(next != last){if(*first == *next){return first;}++first;++next;}}return last;
}bool myfunction(int i,int j){return (i == j);
}int main(){int myints[] = {5,20,5,30,30,20,10,10,20};std::vector<int>my_vector(myints,myints+8);std::vector<int>::iterator it;//using default comparisonit = std::adjacent_find(my_vector.begin(),my_vector.end());if (it != my_vector.end())std::cout << "The first pair of repeated elements are:" << *it << '\n';//using predicate comparison//it當(dāng)前指定的位置是30, 自增錯(cuò)過相鄰的一堆元素 30it = std::adjacent_find(++it,my_vector.end(), myfunction);if (it != my_vector.end())std::cout << "The first pair of repeated elements are:" << *it << '\n';
}///Users/chy/Desktop/exceptional/cmake-build-debug/exceptional
//The first pair of repeated elements are:30
//The first pair of repeated elements are:10
//
//Process finished with exit code 0
Count
運(yùn)用equality操作符號,將[first,last)內(nèi)的所有元素和指定的數(shù)值value進(jìn)行比較,并返回和value相等的個(gè)數(shù)
template <class InputIterator,class T>
typename std::iterator_traits<InputIterator>::difference_type
count(InputIterator first,InputIterator last,const T& value){typename std::iterator_traits<InputIterator>::difference_type ret = 0;while (first!=last){if (*first == value){++ret;}++first;}return ret;
}
// count algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::count
#include <vector> // std::vectorint main () {// counting elements in array:int myints[] = {10,20,30,30,20,10,10,20}; // 8 elementsint mycount = std::count (myints, myints+8, 10);std::cout << "10 appears " << mycount << " times.\n";// counting elements in container:std::vector<int> myvector (myints, myints+8);mycount = std::count (myvector.begin(), myvector.end(), 20);std::cout << "20 appears " << mycount << " times.\n";return 0;
}
count_if
使用仿函數(shù)pred實(shí)施于[first,last) 區(qū)間內(nèi)的每一個(gè)元素身上,只要仿函數(shù)pred返回為true就進(jìn)行計(jì)數(shù)
template <class InputIterator,class UnaryPredicate>
typename std::iterator_traits<InputIterator>::difference_type
count_if(InputIterator first,InputIterator last,UnaryPredicate pred){typename std::iterator_traits<InputIterator>::difference_type ret = 0;while (first!=last){if (pred(*first)){++ret;}++first;}return ret;
}
// count_if example
#include <iostream> // std::cout
#include <algorithm> // std::count_if
#include <vector> // std::vectorbool IsOdd (int i) { return ((i%2)==1); }int main () {std::vector<int> myvector;for (int i=1; i<10; i++) myvector.push_back(i); // myvector: 1 2 3 4 5 6 7 8 9int mycount = count_if (myvector.begin(), myvector.end(), IsOdd);std::cout << "myvector contains " << mycount << " odd values.\n";return 0;
}
find函數(shù)
循環(huán)查找,找到第一個(gè)匹配的條件者,返回一個(gè)迭代器指向這個(gè)元素,否則返回迭代器last
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 example
#include <iostream> // std::cout
#include <algorithm> // std::find
#include <vector> // std::vectorint main () {// using std::find with array and pointer:int myints[] = { 10, 20, 30, 40 };int * p;p = std::find (myints, myints+4, 30);if (p != myints+4)std::cout << "Element found in myints: " << *p << '\n';elsestd::cout << "Element not found in myints\n";// using std::find with vector and iterator:std::vector<int> myvector (myints,myints+4);std::vector<int>::iterator it;it = find (myvector.begin(), myvector.end(), 30);if (it != myvector.end())std::cout << "Element found in myvector: " << *it << '\n';elsestd::cout << "Element not found in myvector\n";return 0;
}
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;
}
// find_if example
#include <iostream> // std::cout
#include <algorithm> // std::find_if
#include <vector> // std::vectorbool 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;
}
find_end
在序列一[first1,last1)的區(qū)間查找序列二[first2,last2)的最后一次出現(xiàn)點(diǎn),如果序列一不存在完全匹配序列二的子序列就返回迭代器last1
如果具備逆向查找的能力,算法的思想就變成了首次出現(xiàn)的地點(diǎn),逆向查找的關(guān)鍵在于迭代器的雙向移動的能力 最后需要將逆向迭代器轉(zhuǎn)化為正向迭代器,而不是直接移動逆向迭代器,因?yàn)檎虻骱湍嫦虻髦g存在奇妙的實(shí)體關(guān)系和邏輯關(guān)系
template<class ForwardIterator1, class ForwardIterator2>ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1,ForwardIterator2 first2, ForwardIterator2 last2)
{if (first2==last2) return last1; // specified in C++11ForwardIterator1 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::vectorbool 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';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';return 0;
}
find_first_of
返回第二個(gè)序列中元素在第一序列第一次匹配的的地點(diǎn) 例子:找出字符串synesthesia中元音字母(第二序列 aeiou),即找出第二序列中任意元素出現(xiàn)于第一序列的地點(diǎn),此例將返回第一個(gè) e; 如果第一序列不包含任何第二序列中的任何元素返回的將是last1 算法第一個(gè)版本使用元素型別提供的equality操作符號,第二版本使用用戶指定的pred二元運(yùn)算符號
template<class InputIterator,class ForwardIterator>
ForwardIterator find_first_of(InputIterator first1,InputIterator last1,ForwardIterator first2,ForwardIterator last2){while (first1 != last1){for (ForwardIterator it = first2;it!=last2;++it) {if (*it == *first1){return first1;}}++first1;}return last1;
}
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>hasstack(mychars,mychars+6);std::vector<char>::iterator it;int needle[] = {'A','B','C'};//using default comparisonit = std::find_first_of(hasstack.begin(),hasstack.end(),needle,needle+3);if (it != hasstack.end()){std::cout << "The first match is: " << *it << '\n';}//using predicate comparisonit = std::find_first_of(hasstack.begin(),hasstack.end(),needle,needle+3, comp_case_insensitive);if (it != hasstack.end()){std::cout << "The first match is: " << *it << '\n';}
}
for_each
將仿函數(shù)定義于[first,last)區(qū)間內(nèi)的每一個(gè)元素的身上 但是仿函數(shù)f不可以改變元素的內(nèi)容,因?yàn)槭褂玫牡鞯念愋投际荌nputIterators,不保證接受賦值的行為 如果需要對元素的數(shù)值進(jìn)行修改,需要使用算法 transform 仿函數(shù)可以返回一個(gè)數(shù)值,但是這個(gè)數(shù)值一般會被忽略
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);
}
void myfunction(int i){ //functionstd::cout << i << ' ';
}struct myclass { //function object typevoid operator()(int i){std::cout << i << ' ';}
}myobject;int main(){std::vector<int>myvector;myvector.emplace_back(10);myvector.emplace_back(20);myvector.emplace_back(30);std::cout << "myvector contains: ";std::for_each(myvector.begin(),myvector.end(), myfunction);std::cout << '\n';std::cout << "myvector contains: ";std::for_each(myvector.begin(),myvector.end(), myobject);
}
generate
將仿函數(shù)gen的運(yùn)算結(jié)果填寫在[first ,last)區(qū)間內(nèi)的所有元素身上 填寫使用的是迭代器所指元素的 assignment 操作符
template <class ForwardIterator, class Generator>void generate ( ForwardIterator first, ForwardIterator last, Generator gen )
{while (first != last) {*first = gen();++first;}
}
//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';
}
generate_n
將仿函數(shù)gen的運(yùn)算結(jié)果填寫在first開始的n個(gè)元素上 填寫使用的是迭代器所指元素的 assignment 操作符
template <class OutputIterator, class Size, class Generator>void generate_n ( OutputIterator first, Size n, Generator gen )
{while (n>0) {*first = gen();++first; --n;}
}
// generate_n example
#include <iostream> // std::cout
#include <algorithm> // std::generate_nint current = 0;
int UniqueNumber () { return ++current; }int main () {int myarray[9] = {0};std::generate_n (myarray, 5, UniqueNumber);std::cout << "myarray contains:";for (int i=0; i<9; ++i)std::cout << ' ' << myarray[i];std::cout << '\n';return 0;
}
includes 應(yīng)用于有序的區(qū)間
判斷序列二是否涵蓋于序列一 兩個(gè)序列都要求有序,其內(nèi)部元素是可以重復(fù)的 涵蓋的含義是其內(nèi)的所有元素都被另外一個(gè)元素包含。 判斷元素是否相等,必須使用less 或者 greater 默認(rèn)使用遞增排序 即operator <? 二者等價(jià) ,less可以省略
std::includes(S1.begin(),S1.end(),S2.begin(),S2.end());std::includes(S1.begin(),S1.end(),S2.begin(),S2.end(),std::less<int>());
如果是按照從大到小進(jìn)行排序,就必須使用仿函數(shù) greater
std::includes(S1.begin(),S1.end(),S2.begin(),S2.end(),std::greater<int>());
兩個(gè)序列的元素都可以重復(fù),S1包含一個(gè)S2的子集合,假設(shè)某個(gè)元素在S2出現(xiàn)n次,在S1出現(xiàn)m次,如果m<n 就會報(bào)錯(cuò)
//最新版
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;
}//舊版
//判斷區(qū)間二 中的每個(gè)元素 數(shù)值是否都存在于區(qū)間一
//區(qū)間一和區(qū)間二都是sorted ranges
template <class InputIterator1,class InputIterator2>
bool includes(InputIterator1 first1,InputIterator1 last1,InputIterator2 first2,InputIterator2 last2){while(first1!=last1 && first2!=last2){if (*first2 < *first1){return false;} else if(*first2 > *first1){++first1;} else{++first1;++first2;}}return first2 == last2;
}//二元運(yùn)算 comp
//前提是序列一和序列二都是 sorted ranges
template <class InputIterator1,class InputIterator2,class Compare>
bool includes(InputIterator1 first1,InputIterator1 last1,InputIterator2 first2,InputIterator2 last2,Compare comp){while(first1!=last1 && first2!=last2){if (comp(*first2,*first1)){return false;} else if(comp(*first1,*first2)){++first1;} else{++first1;++first2;}}return first2 == last2;
}
版本二? 如果你傳入了一個(gè)二元運(yùn)算符comp,卻不能使以下的case3代表兩個(gè)元素相等
這個(gè)comp會導(dǎo)致整個(gè)includes算法語義錯(cuò)誤。但是comp的型別是Compare既不是BinaryPredicate 也不是BinaryOperation,所以并非隨便一個(gè)二元運(yùn)算符號都可以用于作為comp的參數(shù)?
// includes algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::includes, std::sortbool 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);// using default comparison:if ( std::includes(container,container+10,continent,continent+4) )std::cout << "container includes continent!\n";// using myfunction as comp:if ( std::includes(container,container+10,continent,continent+4, myfunction) )std::cout << "container includes continent!\n";return 0;
}
max_element
template <class ForwardIterator>
ForwardIterator max_element(ForwardIterator first,ForwardIterator last){if (first==last){return last;}ForwardIterator largest = first;while(++first!=last){if(*largest < *first){largest = first;}}return largest;
}
Merge 應(yīng)用于有序區(qū)間
將兩個(gè)排序的集合S1和S2,合并起來置于另外一段空間,得到一個(gè)有序的序列 返回一個(gè)迭代器指向最后的結(jié)果序列的最后一個(gè)元素的位置
template <class InputIterator1,class InputIterator2,class OutputIterator>
OutputIterator merge(InputIterator1 first1,InputIterator1 last1,InputIterator2 first2,InputIterator2 last2,OutputIterator result){while(first1 != last1 && first2 != last2){ //兩個(gè)都尚未走完if (*first2 < *first1){*result = *first2;++first2;} else{*result = *first1;++first1;}++result;}return std::copy(first2,last2,std::copy(first1,last2,result));
}
template <class InputIterator1,class InputIterator2,class OutputIterator>
OutputIterator merge(InputIterator1 first1,InputIterator1 last1,InputIterator2 first2,InputIterator2 last2,OutputIterator result){while (true){if (first1 == last1){std::copy(first2,last2,result);}if (first2 == last2){std::copy(first1,last1,result);}*result++ = (*first1 < *first2) ? *first1++ : *first2++;}
}
// includes algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::includes, std::sortbool 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);std::vector<int>v(14,0);std::merge(container,container+10,continent,continent+4,v.begin());for(auto x : v){std::cout << x << ' ';}//5 10 10 15 20 20 25 30 30 35 40 40 45 50 return 0;
}
min_element
template <class ForwardIterator>ForwardIterator min_element ( ForwardIterator first, ForwardIterator last )
{if (first==last) return last;ForwardIterator smallest = first;while (++first!=last)if (*first<*smallest) // or: if (comp(*first,*smallest)) for version (2)smallest=first;return smallest;
}
// min_element/max_element example
#include <iostream> // std::cout
#include <algorithm> // std::min_element, std::max_elementbool 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;
}
?partition
partition會重新排列區(qū)間內(nèi)的元素,將所有被一元條件pred判定為true的元素排列在區(qū)間的前段,判定為false的元素排列在后端 不穩(wěn)定算法 不保持相對次序不變 如果想保證相對次序不變 使用 stable_partition
template <class BidirectionalIterator,class UnaryPredicate>
BidirectionalIterator partition(BidirectionalIterator first,BidirectionalIterator last, UnaryPredicate pred){while(first != last){while(pred(*first)){++first;if (first == last){return first;}}do{--last;if (first == last){return first;}} while (!pred(*last));std::swap(*first,*last);++first;}
}
remove 移除但是不刪除
?將每一個(gè)不與value相等的元素輪番賦值給first之后的空間 返回的ForwardIterator標(biāo)示出重新整理后的最后元素的下一個(gè)位置 例子:序列{0,1,0,2,0,3,0,4} 移除0元素之后變成 {1,2,3,4,0,3,0,4}每一個(gè)與0不相等的元素被拷貝到一、二、三、四個(gè)位置,即第四個(gè)位置之后是這個(gè)算法的殘余數(shù)據(jù) array不適用于remove 和 remove_if,因?yàn)閍rray無法縮小尺寸,導(dǎo)致殘余的數(shù)據(jù)一直存在 對于array,比較適用的算法是remove_copy()和remove_copy_if
template <class ForwardIterator,class T>
ForwardIterator remove(ForwardIterator first,ForwardIterator last,const T& value){ForwardIterator result = first;while(first!=last){if (!(*first==value)){if(!(first==result)){*result = *first;}++result;}++first;}return result;
}
int main () {int myints[] = {10,20,30,30,20,10,10,20}; // 10 20 30 30 20 10 10 20//bounds of rangeint* begin = myints;int* end = myints + (sizeof (myints)/sizeof (int));end = std::remove(begin,end,20);std::cout << "range contains:";for(int* ptr = begin;ptr!=end;++ptr){std::cout << *ptr << ' ';}std::cout << '\n';
}
remove_copy
將每一個(gè)不與value相等的元素輪番賦值給result開始的起始容器 新的容器可以和先前的容器重疊,但是對于新的容器賦值超越了舊的容器的大小會產(chǎn)生無法預(yù)期的后果 返回值OutputIterator會指向被復(fù)制的最后元素的下一個(gè)位置
template <class ForwardIterator,class OutputIterator,class T>
ForwardIterator remove(ForwardIterator first,ForwardIterator last,OutputIterator result,const T& value){while(first!=last){if (!(*first==value)){*result = *first;++result;}++first;}return result;
}
int main () {int myints[] = {10,20,30,30,20,10,10,20}; // 10 20 30 30 20 10 10 20//bounds of rangeint* begin = myints;int* end = myints + (sizeof (myints)/sizeof (int));std::vector<int>myvector(5);std::remove_copy(begin,end,myvector.begin(),20);std::cout << "range contains:";for(auto ptr = myvector.begin();ptr!=myvector.end();++ptr){std::cout << *ptr << ' ';}std::cout << '\n';
}
remove_if
?將每一個(gè)被pred核定為true的元素輪番賦值給first之后的空間,并不會真的刪除元素 返回的ForwardIterator標(biāo)示出重新整理后的最后元素的下一個(gè)位置 可以通過將迭代器交給所在容器的erase member function array不適用于remove 和 remove_if,因?yàn)閍rray無法縮小尺寸,導(dǎo)致殘余的數(shù)據(jù)一直存在 對于array,比較適用的算法是remove_copy()和remove_copy_if
template <class ForwardIterator,class UnaryPredicate>
ForwardIterator remove_if(ForwardIterator first,ForwardIterator last,UnaryPredicate pred){ForwardIterator result = first;while(first!=last){if (!pred(*first)){if (result != first){*result = *first;}++result;}++first;}return result;
}
// remove_if example
#include <iostream> // std::cout
#include <algorithm> // std::remove_ifbool myfunction (int i, int j) { return i<j; }int main () {int myints[] = {1,2,3,4,5,6,7,8,9}; // 1 2 3 4 5 6 7 8 9// bounds of range:int* pbegin = myints; // ^int* pend = myints+sizeof(myints)/sizeof(int); // ^ ^pend = std::remove_if (pbegin, pend, IsOdd); // 2 4 6 8 ? ? ? ? ?// ^ ^std::cout << "the range contains:";for (int* p=pbegin; p!=pend; ++p)std::cout << ' ' << *p;std::cout << '\n';return 0;
}
remove_copy_if
?將每一個(gè)被pred核定為true的元素賦值給result開始的空間,并不會真的刪除元素 可以通過將迭代器交給所在容器的erase member function array不適用于remove 和 remove_if,因?yàn)閍rray無法縮小尺寸,導(dǎo)致殘余的數(shù)據(jù)一直存在 對于array,比較適用的算法是remove_copy()和remove_copy_if
template <class InputIterator, class OutputIterator, class UnaryPredicate>OutputIterator remove_copy_if (InputIterator first, InputIterator last,OutputIterator result, UnaryPredicate pred)
{while (first!=last) {if (!pred(*first)) {*result = *first;++result;}++first;}return result;
}
// remove_copy_if example
#include <iostream> // std::cout
#include <algorithm> // std::remove_copy_if
#include <vector> // std::vectorbool IsOdd (int i) { return ((i%2)==1); }int main () {int myints[] = {1,2,3,4,5,6,7,8,9};std::vector<int> myvector (9);std::remove_copy_if (myints,myints+9,myvector.begin(),IsOdd);std::cout << "myvector contains:";for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}
replace
將指定區(qū)間內(nèi)的所有舊的元素使用新的數(shù)值進(jìn)行替換
template <class ForwardIterator, class T>void replace (ForwardIterator first, ForwardIterator last,const T& old_value, const T& new_value)
{while (first!=last) {if (*first == old_value) *first=new_value;++first;}
}
// replace algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::replace
#include <vector> // std::vectorint main () {int myints[] = { 10, 20, 30, 30, 20, 10, 10, 20 };std::vector<int> myvector (myints, myints+8); // 10 20 30 30 20 10 10 20std::replace (myvector.begin(), myvector.end(), 20, 99); // 10 99 30 30 99 10 10 99std::cout << "myvector contains:";for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}
replace_copy
將新的序列復(fù)制到result指定的容器 返回的OutputIterator指向被復(fù)制的最后一個(gè)元素的下一個(gè)位置 并不會改變先前的序列
template < class ForwardIterator, class UnaryPredicate, class T >void replace_if (ForwardIterator first, ForwardIterator last,UnaryPredicate pred, const T& new_value)
{while (first!=last) {if (pred(*first)) *first=new_value;++first;}
}
// replace_if example
#include <iostream> // std::cout
#include <algorithm> // std::replace_if
#include <vector> // std::vectorbool 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 9std::replace_if (myvector.begin(), myvector.end(), IsOdd, 0); // 0 2 0 4 0 6 0 8 0std::cout << "myvector contains:";for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}
replace_if
將pred判定為true的元素使用新值進(jìn)行替換
template < class ForwardIterator, class UnaryPredicate, class T >void replace_if (ForwardIterator first, ForwardIterator last,UnaryPredicate pred, const T& new_value)
{while (first!=last) {if (pred(*first)) *first=new_value;++first;}
}
// replace_if example
#include <iostream> // std::cout
#include <algorithm> // std::replace_if
#include <vector> // std::vectorbool 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 9std::replace_if (myvector.begin(), myvector.end(), IsOdd, 0); // 0 2 0 4 0 6 0 8 0std::cout << "myvector contains:";for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}
replace_copy_if
其行為類似replace_if()? 新的序列會被復(fù)制到result指定的區(qū)間內(nèi) 返回的OutputIterator指向被復(fù)制的最后一個(gè)元素的下一個(gè)位置 并不會改變先前的序列
template <class InputIterator, class OutputIterator, class UnaryPredicate, class T>OutputIterator replace_copy_if (InputIterator first, InputIterator last,OutputIterator result, UnaryPredicate pred,const T& new_value)
{while (first!=last) {*result = (pred(*first))? new_value: *first;++first; ++result;}return result;
}
// replace_copy_if example
#include <iostream> // std::cout
#include <algorithm> // std::replace_copy_if
#include <vector> // std::vectorbool IsOdd (int i) { return ((i%2)==1); }int main () {std::vector<int> foo,bar;// set some values:for (int i=1; i<10; i++) foo.push_back(i); // 1 2 3 4 5 6 7 8 9bar.resize(foo.size()); // allocate spacestd::replace_copy_if (foo.begin(), foo.end(), bar.begin(), IsOdd, 0);// 0 2 0 4 0 6 0 8 0std::cout << "bar contains:";for (std::vector<int>::iterator it=bar.begin(); it!=bar.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}
reverse
將序列中的元素在原有的容器中顛倒重排 根據(jù)迭代器的類型 (雙向迭代器或者隨機(jī)迭代器)進(jìn)行偏特化設(shè)計(jì)
template <class BidirectionalIterator>void reverse (BidirectionalIterator first, BidirectionalIterator last)
{while ((first!=last)&&(first!=--last)) {std::iter_swap (first,last);++first;}
}
// reverse algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::reverse
#include <vector> // std::vectorint 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 9std::reverse(myvector.begin(),myvector.end()); // 9 8 7 6 5 4 3 2 1// 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;
}
reverse_copy_if
行為類似reverse 新的序列會被復(fù)制到result指定的區(qū)間內(nèi) 返回的OutputIterator指向被復(fù)制的最后一個(gè)元素的下一個(gè)位置 并不會改變先前的序列
template <class BidirectionalIterator, class OutputIterator>OutputIterator reverse_copy (BidirectionalIterator first,BidirectionalIterator last, OutputIterator result)
{while (first!=last) {--last;*result = *last;++result;}return result;
}
// reverse_copy example
#include <iostream> // std::cout
#include <algorithm> // std::reverse_copy
#include <vector> // std::vectorint main () {int myints[] ={1,2,3,4,5,6,7,8,9};std::vector<int> myvector;myvector.resize(9); // allocate spacestd::reverse_copy (myints, myints+9, myvector.begin());// 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;
}
rotate
將[first,middle)和[middle,last)內(nèi)的元素互換 middle指向的元素會成為容器的第一個(gè)元素 其功能類似swap_ranges,但是swap_ranges只能交換兩個(gè)長度相同的區(qū)間 rotate可以交換兩個(gè)長度不同的區(qū)間
template <class ForwardIterator>void rotate (ForwardIterator first, ForwardIterator middle,ForwardIterator last)
{ForwardIterator next = middle;while (first!=next){swap (*first++,*next++);if (next==last) next=middle;else if (first==middle) middle=next;}
}
先交換元素的數(shù)值,再進(jìn)行迭代器的遞增
int main () {int myints[] = {1,2,3,4,5,6,7,8,9}; // 1 2 3 4 5 6 7 8 9std::vector<int>myvector(myints,myints+9);std::rotate(myvector.begin(),myvector.begin()+3,myvector.end());std::cout << "the range contains:";for (auto temp : myvector)std::cout << ' ' << temp;std::cout << '\n'; //the range contains: 4 5 6 7 8 9 1 2 3return 0;
}
?rote_copy
類似于rote 將產(chǎn)生的新的序列置于result所指出的容器中 返回的OutputIterator指向被復(fù)制的最后一個(gè)元素的下一個(gè)位置 并不會改變先前的序列 操作過程:將后端復(fù)制到新的容器的開端,再將前段內(nèi)容復(fù)制到新的容器
template <class ForwardIterator,class OutputIterator>
OutputIterator rotate_copy(ForwardIterator first,ForwardIterator middle,ForwardIterator last,OutputIterator result){result = std::copy(middle,last,result);return std::copy(first,middle,result);
}
int main () {int myints[] = {1,2,3,4,5,6,7,8,9}; // 1 2 3 4 5 6 7 8 9std::vector<int>myvector(myints,myints+9);std::vector<int>my_tmp(9,0);std::rotate_copy(myvector.begin(),myvector.begin()+3,myvector.end(),my_tmp.begin());std::cout << "the range contains:";for (auto temp : my_tmp)std::cout << ' ' << temp;std::cout << '\n'; //the range contains: 4 5 6 7 8 9 1 2 3
// myvector the range contains: 1 2 3 4 5 6 7 8 9return 0;
}
?Search
在序列一種查找序列二中首次出現(xiàn)的點(diǎn) 如果不存在完全匹配的子序列,返回序列一的last
template <class ForwardIterator1,class ForwardIterator2>
ForwardIterator1 search(ForwardIterator1 first1,ForwardIterator1 last1,ForwardIterator2 first2,ForwardIterator2 last2){if(first2 == last2) return first1;while(first1 != last1){ForwardIterator1 it1 = first1;ForwardIterator2 it2 = first2;while (*it1 == *it2){++it1;++it2;if (*it2==last2)return first1;if (*it1==last1)return last1;}++first1;}return last1;
}
// search algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::search
#include <vector> // std::vectorbool mypredicate (int i, int j) {return (i==j);
}int main () {std::vector<int> haystack;// set some values: haystack: 10 20 30 40 50 60 70 80 90for (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';elsestd::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';elsestd::cout << "needle2 not found\n";return 0;
}
search_n
查找連續(xù)幾個(gè)符合條件的元素組成的子序列,返回一個(gè)迭代器指向該子序列起始的地方,找不到返回迭代器last 版本一使用 equality 版本二使用 用戶指定的某個(gè)二元函數(shù),使用仿函數(shù)實(shí)現(xiàn) 例子:面對序列 {10,8,8,4,5,2,3,4}查找連續(xù)兩個(gè)8形成的子序列起點(diǎn) iter1 = search_n (iv.begin(),iv.end(),2,8); 例子:面對序列 {10,8,8,4,5,2,3,4}查找連續(xù)三個(gè)小于8的子序列起點(diǎn) iter1 = search_n (iv.begin(),iv.end(),3,8,std::less<int>());
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){++it;if (++i == count){return first;}}++first;}return last;
}
// search_n example
#include <iostream> // std::cout
#include <algorithm> // std::search_n
#include <vector> // std::vectorbool 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';elsestd::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';elsestd::cout << "match not found\n";return 0;
}
swap_ranges
將[first1 ,last1) 區(qū)間內(nèi)的元素和從[first2 開始個(gè)數(shù)相同的元素互相交換 兩個(gè)區(qū)間不限定是否從屬于同一個(gè)區(qū)間 ,可以相同 可以不同 如果第二個(gè)序列的長度小于第一個(gè)序列的長度,或者兩個(gè)序列在同一個(gè)序列中出現(xiàn)重疊,執(zhí)行結(jié)果是不可預(yù)期的 此算法返回一個(gè)迭代器 指向第二序列中最后一個(gè)被交換元素的下一個(gè)位置
template <class ForwardIterator1,class ForwardIterator2>
ForwardIterator2 swap_ranges(ForwardIterator1 first1,ForwardIterator1 last1,ForwardIterator2 first2){while(first1 != last1){std::swap(*first1,*first2);++first1;++first2;}return first2;
}
// swap_ranges example
#include <iostream> // std::cout
#include <algorithm> // std::swap_ranges
#include <vector> // std::vectorint main () {std::vector<int> foo (5,10); // foo: 10 10 10 10 10std::vector<int> bar (5,33); // bar: 33 33 33 33 33std::swap_ranges(foo.begin()+1, foo.end()-1, bar.begin());// print out results of swap:std::cout << "foo contains:";for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';std::cout << "bar contains:";for (std::vector<int>::iterator it=bar.begin(); it!=bar.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}
transform
第一版本使用仿函數(shù)op作用于區(qū)間中每一個(gè)元素的身上,產(chǎn)生一個(gè)新的序列 第二版本使用仿函數(shù)binary_op作用于一雙元素的身上,第一個(gè)元素來自[first,last1),第二個(gè)元素來自從first2開始的序列,如果第二序列元素少,會出錯(cuò) 兩個(gè)版本的transform都會把結(jié)果放進(jìn)迭代器result所標(biāo)示的容器中 result可以指向源端容器,造成數(shù)據(jù)的覆蓋 返回迭代器指向的是結(jié)果序列的最后元素的下一個(gè)位置
template <class InputIterator, class OutputIterator, class UnaryOperator>OutputIterator transform (InputIterator first1, InputIterator last1,OutputIterator result, UnaryOperator op)
{while (first1 != last1) {*result = op(*first1); // or: *result=binary_op(*first1,*first2++);++result; ++first1;}return result;
}
// transform algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::transform
#include <vector> // std::vector
#include <functional> // std::plusint op_increase (int i) { return ++i; }int main () {std::vector<int> foo;std::vector<int> bar;// set some values:for (int i=1; i<6; i++)foo.push_back (i*10); // foo: 10 20 30 40 50bar.resize(foo.size()); // allocate spacestd::transform (foo.begin(), foo.end(), bar.begin(), op_increase);// bar: 11 21 31 41 51// std::plus adds together its two arguments:std::transform (foo.begin(), foo.end(), bar.begin(), foo.begin(), std::plus<int>());// foo: 21 41 61 81 101std::cout << "foo contains:";for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}
unique
移除相鄰重復(fù)的元素 移除所有重復(fù)的元素需要實(shí)現(xiàn)排序 返回的迭代器指向新的區(qū)間的尾端,新區(qū)間內(nèi)容不重復(fù) 算法是穩(wěn)定的,其所有保留下來的元素,其原始相對次序不改變
template <class ForwardIterator>ForwardIterator unique (ForwardIterator first, ForwardIterator last)
{if (first==last) return last;ForwardIterator result = first;while (++first != last){if (!(*result == *first)) // or: if (!pred(*result,*first)) for version (2)*(++result)=*first;}return ++result;
}
// unique algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::unique, std::distance
#include <vector> // std::vectorbool myfunction (int i, int j) {return (i==j);
}int main () {int myints[] = {10,20,20,20,30,30,20,20,10}; // 10 20 20 20 30 30 20 20 10std::vector<int> myvector (myints,myints+9);// using default comparison:std::vector<int>::iterator it;it = std::unique (myvector.begin(), myvector.end()); // 10 20 30 20 10 ? ? ? ?// ^myvector.resize( std::distance(myvector.begin(),it) ); // 10 20 30 20 10// using predicate comparison:std::unique (myvector.begin(), myvector.end(), myfunction); // (no changes)// print out content:std::cout << "myvector contains:";for (it=myvector.begin(); it!=myvector.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}
unique_copy
template <class InputIterator, class OutputIterator>OutputIterator unique_copy (InputIterator first, InputIterator last,OutputIterator result)
{if (first==last) return result;*result = *first;while (++first != last) {typename iterator_traits<InputIterator>::value_type val = *first;if (!(*result == val)) // or: if (!pred(*result,val)) for version (2)*(++result)=val;}return ++result;
}
// unique_copy example
#include <iostream> // std::cout
#include <algorithm> // std::unique_copy, std::sort, std::distance
#include <vector> // std::vectorbool myfunction (int i, int j) {return (i==j);
}int main () {int myints[] = {10,20,20,20,30,30,20,20,10};std::vector<int> myvector (9); // 0 0 0 0 0 0 0 0 0// using default comparison:std::vector<int>::iterator it;it=std::unique_copy (myints,myints+9,myvector.begin()); // 10 20 30 20 10 0 0 0 0// ^std::sort (myvector.begin(),it); // 10 10 20 20 30 0 0 0 0// ^// using predicate comparison:it=std::unique_copy (myvector.begin(), it, myvector.begin(), myfunction);// 10 20 30 20 30 0 0 0 0// ^myvector.resize( std::distance(myvector.begin(),it) ); // 10 20 30// print out content:std::cout << "myvector contains:";for (it=myvector.begin(); it!=myvector.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}
總結(jié)
以上是生活随笔 為你收集整理的STL源码剖析 数值算法 heap算法 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。