boost I 常用算法组件
目錄
一、foreach
二、minmax
(一)boost.minmax
1.std::min與std::max
2.boost::minmax
3.std::minmax(推薦)
(二)boost.minmax_element
1.std::min_element與std::max_element
2.std::minmax_element
3.boost::minmax_element
4.boost.xxx_[min|max]_yyy[min|max]_element?
三、algorithm
(一)clamp
1.boost::algorithm::clamp
2.boost::algorithm::clamp_range
(二)hex
????????本文主要總結(jié)boost庫(kù)中實(shí)用的三個(gè)組件:foreach、minmax、algorithm。
一、foreach
????????C++11引入了auto for循環(huán),它雖然比老式的 for 循環(huán)更加簡(jiǎn)潔,更清晰地表明了代碼編寫者的意圖,使用它不容易犯遍歷不全或越界的錯(cuò)誤。但有些時(shí)候我們使用的編譯器不一定支持 C++ 的這個(gè)新特性,所以也就無(wú)法享受這一便利。
????????Boost的 foreach 庫(kù)使用宏彌補(bǔ)了這個(gè)遺憾,它提供類似形式的序列遍歷功能,簡(jiǎn)便好用,不需要使用麻煩的迭代器,也不需要定義新的函數(shù)對(duì)象,而且它還具有 C ++ 標(biāo)準(zhǔn)所沒有的反向遍歷的能力。
????????foreach庫(kù)提供兩個(gè)宏 BOOST_FOREACH 和BOOST_REVERSE_FOREACH,分別來(lái)實(shí)現(xiàn)對(duì)序列的正向遍歷和反向遍歷。使用foreach時(shí)要注意一點(diǎn),它遍歷序列有一個(gè)前提:假設(shè)序列是穩(wěn)定的,也就是說(shuō)在循環(huán)中不能改變序列的長(zhǎng)度,也不能增減序列的元素,否則會(huì)導(dǎo)致遍歷使用的迭代器失效,發(fā)生未定義錯(cuò)誤。
????????如果在遍歷時(shí)需要使用元素或者修改元素,則需要用引用的形式。auto 關(guān)鍵字可以加const或 & 來(lái)修飾,用來(lái)推導(dǎo)常量或引用類型,通常用 auto & 的形式最好,因?yàn)樗梢员苊鉄o(wú)謂的拷貝。
#include <boost/foreach.hpp> #include <boost/array.hpp> void TestForeach() {boost::array<int, 3> _array{ 1,2,3 };std::cout << "正向遍歷:";BOOST_FOREACH(auto& i, _array){std::cout << i << ",";//正向遍歷:1, 2, 3,}std::cout << std::endl << "反向遍歷:";BOOST_REVERSE_FOREACH(auto& i, _array){std::cout << i << ",";//反向遍歷:3, 2, 1,} }????????BOOST_FOREACH 支持所有標(biāo)準(zhǔn)容器、原始數(shù)組、 C 字符串及元素是迭代器的std::pair。此外,BOOST_FOREACH 還支持 Boost 庫(kù)內(nèi)的大部分容器類型。(C++標(biāo)準(zhǔn)的for循環(huán)不支持元素是迭代器的std::pair序列。)
std::pair<int*, int*> _pair(_array.begin(), _array.end());//注意_pair里的元素是迭代器BOOST_FOREACH(auto i, _pair){std::cout << i << " ";}//for不支持//for(auto i:_pair)//{// std::cout << i << " ";//}?????????BOOST_FOREACH 是宏,這的確有時(shí)會(huì)帶來(lái)問題。當(dāng)變量聲明是一個(gè)“含有逗號(hào)的”模板類型時(shí),它就會(huì)失效(因?yàn)轭A(yù)處理器不能識(shí)別模板的"<>"),解決方法有:
- 使用auto關(guān)鍵字來(lái)自動(dòng)推導(dǎo)變量類型;
- 使用boost.utility庫(kù)中的BOOST_IDENTITY_TYPE宏。
二、minmax
????????minmax庫(kù)是對(duì) C++ 標(biāo)準(zhǔn)庫(kù)中的算法 std::min/max 和 std::min_element/max_element的增強(qiáng),可在一次處理中同時(shí)獲得最大值和最小值,在執(zhí)行效率上有很大提高,它們已經(jīng)被收入C++標(biāo)準(zhǔn)。
(一)boost.minmax
1.std::min與std::max
std::cout << "100和101的最小值:" << std::min(100, 101) << std::endl;std::cout << "100和101的最大值:" << std::max(100, 101) << std::endl;2.boost::minmax
????????boost::minmax返回的是一個(gè)包含兩個(gè)元素的tuple類型,第一個(gè)元素是最小值,第二個(gè)元素是最大值。
#include <boost/algorithm/minmax.hpp>boost::tuple<const int&, const int&> tuple = boost::minmax(100, 101);std::cout << "100和101的最小值:" << tuple.get<0>() << std::endl;std::cout << "100和101的最大值:" << tuple.get<1>() << std::endl;3.std::minmax(推薦)
????????std::minmax不僅兼容了boost::minmax,還支持初始化列表參數(shù)。需要注意的是std::minmax返回的類型是std::pair,而不是tuple。
std::pair< const int&, const int&> pair = std::minmax(100, 101);std::cout << "100和101的最小值:" << pair.first << std::endl;std::cout << "100和101的最大值:" << std::get<1>(pair) << std::endl;std::pair< const int&, const int&> pair = std::minmax({ 100,101,102 });(二)boost.minmax_element
????????minmax_element 并不是一個(gè)算法,而是一個(gè)算法族,包括 first_min_element、last_min_element、first_min_first_max _element等—系列類似的算?法。minmax_element 是其中最基本、最常用的算法。
【tips:begin()函數(shù)】
1.標(biāo)準(zhǔn)容器的begin()返回迭代器。迭代器中的元素是指針,指針指向第一個(gè)元素。對(duì)迭代器加*,即獲得該迭代器所指的元素;對(duì)迭代器加*,再加&,就是該元素的地址。
2.boost容器begin()返回指針。指針指向第一個(gè)元素,類似標(biāo)準(zhǔn)容器的data()。
std::array<int, 3> array1{ 1,2,3 }; //標(biāo)準(zhǔn)庫(kù)printf("%p\n", array1.data()); //00000010E4CFEE58printf("%p\n", &*array1.begin()); //00000010E4CFEE58printf("%p\n", &*(array1.end() - 1));//00000010E4CFEE60printf("%p\n", &array1[0]); //00000010E4CFEE58printf("%p\n", &array1[1]); //00000010E4CFEE5Cprintf("%p\n", &*std::begin(array1));//00000010E4CFEE58boost::array<int, 8> _array{ 1,2,1,8,3,4,5,8 };//boost::arrayprintf("%p\n", _array.begin()); //00000082D5D4F108printf("%p\n", &_array[0]); //00000082D5D4F1083.C++11 標(biāo)準(zhǔn)庫(kù)新增加的std::begin() 和std::end() 函數(shù)和 std::vector 容器包含的 begin() 和 end() 成員函數(shù)不同,標(biāo)準(zhǔn)庫(kù)提供的這 2 個(gè)函數(shù)的操作對(duì)象,既可以是容器,還可以是普通數(shù)組。當(dāng)操作對(duì)象是容器時(shí),它和容器包含的 begin() 和 end() 成員函數(shù)的功能完全相同;如果操作對(duì)象是普通數(shù)組,則 begin() 函數(shù)返回的是指向數(shù)組第一個(gè)元素的指針,同樣 end() 返回指向數(shù)組中最后一個(gè)元素之后一個(gè)位置的指針(注意不是最后一個(gè)元素)。?
int a[3] = { 1,2,3 };std::begin(a);//返回int*std::vector<int> vector{ 1,1,3,2,1,3,3,1 };std::begin(vector);//返回iterator1.std::min_element與std::max_element
????????當(dāng)序列中元素有重復(fù)時(shí),std::min_element返回序列中第一個(gè)最小的,std::max_element返回序列中第一個(gè)最大的。
std::vector<int> vector{1,1,3,2,1,3,3,1};auto minPointer = std::min_element(vector.begin(), vector.end());std::cout << "vector中的最小元素:" << *minPointer << std::endl;//1auto maxPointer = std::max_element(vector.begin(), vector.end());std::cout << "vector中的最大元素:" << *maxPointer << std::endl;//32.std::minmax_element
????????當(dāng)序列中元素有重復(fù)時(shí),std::minmax_element返回元素中第一個(gè)最小的,最后一個(gè)最大的。
std::vector<int> vector{1,1,3,2,1,3,3,1};auto _pair = std::minmax_element(vector.begin(), vector.end());std::cout << "vector中的最小元素:" << *_pair.first << std::endl;//1std::cout << "vector中的最大元素:" << *std::get<1>(_pair) << std::endl;//3printf("%p\n", vector.begin()._Ptr); //00000174B39EBD90printf("%p\n", &*vector.begin()); //00000174B39EBD90printf("%p\n", (vector.end()-1)._Ptr);//00000174B39EBDACprintf("%p\n", _pair.first._Ptr); //00000174B39EBD90printf("%p\n", _pair.second._Ptr); //00000174B39EBDA83.boost::minmax_element
????????當(dāng)序列中(不論是標(biāo)準(zhǔn)庫(kù)的還是boost庫(kù)的容器)元素有重復(fù)時(shí),boost::minmax_element返回元素中第一個(gè)最小的,第一個(gè)最大的。
????????注意:std::minmax_element與boost::minmax_element返回的迭代器不同。
#include <boost/algorithm/minmax_element.hpp>boost::array<int, 8> _array{ 1,2,1,8,3,4,5,8 };std::pair<int*, int*> _pair1 = boost::minmax_element(_array.begin(), _array.end());std::cout << "_array中的最小元素:" << *_pair1.first << std::endl;std::cout << "_array中的最大元素:" << *std::get<1>(_pair1) << std::endl;printf("%p\n", _array.begin()); //00000082D5D4F108printf("%p\n", &_array[0]); //00000082D5D4F108printf("%p\n", _pair1.first); //00000082D5D4F108printf("%p\n", _pair1.second); //00000082D5D4F1144.boost.xxx_[min|max]_yyy[min|max]_element?
????????minmax_element ( ) 函數(shù)的其他同族函數(shù)用于序列中存在相同元素的情況,它們可以找到第一個(gè)或最后一個(gè)最大值或最小值,形式為xxx_[min|max]_yyy[min|max]_element( ),其中的 xxx 和 yyy 可以是 first 或 last 。
boost::array<int, 8> _array{ 1,2,1,8,3,4,5,8 };std::pair<int*, int*> _pair2 = boost::last_min_first_max_element(_array.begin(), _array.end());std::cout << "_array中的最后一個(gè)最小元素:" << *_pair2.first << std::endl;std::cout << "_array中的第一個(gè)最大元素:" << *std::get<1>(_pair2) << std::endl;printf("%p\n", _pair2.first); //00000082D5D4F110printf("%p\n", _pair2.second); //00000082D5D4F114三、algorithm
(一)clamp
1.boost::algorithm::clamp
????????顧名思義 , clamp 用來(lái)判斷一個(gè)值是否 " 夾 " 在另外一對(duì)值之間,其常用聲明如下 :
template<typename T> T const& clamp (const T& val,const T& lo,const T& hi);函數(shù)的參數(shù) lo 和 hi 確定了一個(gè)閉區(qū)間,其算法的邏輯如下:
- 如果 val 在區(qū)間內(nèi),那么返回 val。
- 如果 val 在區(qū)間左邊 (val < lo ),那么返回 lo。
- 如果 val 在區(qū)間右邊 ( hi < val ),那么返回 hi。
2.boost::algorithm::clamp_range
????????clamp_range可以對(duì)一組元素執(zhí)行clamp算法,遵循clamp算法邏輯,然后把結(jié)果寫入一個(gè)輸出迭代器中。
#include <boost/algorithm/clamp.hpp> void TestClamp() {int value1 = boost::algorithm::clamp(3, 1, 5);std::cout << "3在[1,5]之間,輸出:" << value1 << std::endl;//3int value2 = boost::algorithm::clamp(3, 4, 6);std::cout << "3在[4,6]左邊,輸出:" << value2 << std::endl;//4int value3 = boost::algorithm::clamp(3, 0, 2);std::cout << "3在[0,2]右邊,輸出:" << value3 << std::endl;//2std::vector<int> vector{ 2,4,6,8,10 };boost::algorithm::clamp_range(vector, std::ostream_iterator<int>(std::cout, ","),0,5);//2 4 5 5 5 }(二)hex
????????hex算法用來(lái)執(zhí)行ASCII字符( "0~9"、"A~F"和"a~f")與十六進(jìn)制字符串的編碼和解碼,包含兩個(gè)互逆的操作:hex/hex_lower 和 unhex 。
ASCII碼一覽表,ASCII碼對(duì)照表 (biancheng.net)
ASCII字符串到16進(jìn)制在線轉(zhuǎn)換工具 - Coding.Tools
#include <boost/algorithm/hex.hpp> void StudyAlgorithm::TestHex() {//ASCII碼123轉(zhuǎn)為十六進(jìn)制字符串313233boost::algorithm::hex("123", std::ostream_iterator<char>(std::cout));//313233//解碼boost::algorithm::unhex("313233", std::ostream_iterator<char>(std::cout));//123//ASCII碼123轉(zhuǎn)為十六進(jìn)制字符串2B2D2A2F,并保存到字符串中std::string value;boost::algorithm::hex("+-*/", std::back_inserter(value));std::cout << value;//2B2D2A2F//小寫boost::algorithm::hex_lower("+-*/", std::back_inserter(value));std::cout << value;//2b2d2a2f }總結(jié)
以上是生活随笔為你收集整理的boost I 常用算法组件的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VR+全景播放器+头控讲解-02
- 下一篇: 加服务器性能无提升,Turbo Boos