日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STL源码剖析 数值算法 heap算法

發(fā)布時(shí)間:2023/12/13 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STL源码剖析 数值算法 heap算法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

算法

  • 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ò),歡迎將生活随笔推薦給好友。