???????????????????????????????? ?
reverse算法擴充
???????????????????????? 內容來源:TCPL和TCPL題解
在TCPL中的19.1習題,有對reverse算法的設計。
template<typename Bi> void reverse(Bi begin, Bi end)
從STL的定義來看,參數輸入的迭代器是雙向迭代器(Bidirectional iterator)。設計起來也是比較容易的。
namespace{
?template<typename Bi>
?inline void reverse(Bi begin, Bi end){
??while(begin != end)
???iter_swap(begin++, --end);
?}
}
而在TCPL的題解里面提到了輸入參數是向前迭代器的情況(Forward iterator)。這樣reverse算法得重新設計。
算法概述:
??? 1.反轉一個向前序列,可以首先將序列分成大致一樣長的兩半。然后用std::swap_ranges算法交換著兩個半長序列。
??? 2.遞歸地反轉這個兩個半長序列。
[注意一下序列元素的個數(奇偶數)]
template<typename For>
void forward_reverse(For begin1, int len)
{
?if(len > 1){
??int half_len = len / 2;
??For end1 = begin1;
??advance(end1, hal_len);
??For begin2 = end1;
??if(len % 2 != 0) //序列個數為奇數
???++begin2;
??std::swap_ranges(begin1, end1, begin2);
??forward_reverse(begin1, half_len);
??forward_reverse(begin2, half_len);
?}
}
再為forward_reverse函數和reverse(bidirection)函數提供一個統(tǒng)一的借口。
template<typename It>
inline void flex_reverse(It begin, It end)
{
?using std::iterator_traits;
?tagged_reverse(begin, end, iterator_traits<It>::iterator_category());
}
tagged_reverse()函數是通過函數重載和迭代器特征類(萃取技術)的結合來完成下面兩個函數的自動選擇。
template<typename For>? //forward_reverse封裝
inline void tagged_reverse(For begin, For end, std::forward_iterator_tag)
{
?forward_reverse(begin, distance(begin, end));
}
template<typename For>? //reverse封裝
inline void tagged_reverse(For begin, For end, std::bidirectional_iterator_tag)
{
?reverse(begin, end);
}
后來我發(fā)現好像把Forward_iterator的容器并不多見。
STL容器:1、雙向迭代器(Bidirectional iterator)
??????????? list、set、multiset、map、multimap
??????? 2、隨機存取迭代器(Random access iterator)
??????????? vector、deque、string
附:iterator_traits模板類中的一組聲明描述:
template<class Iter> struct iterator_traits
{
?typedef typename Iter::iterator_category iterator_category;
?typedef typename Iter::value_type value_type;
?typedef typename Iter::difference_type difference_type;
?typedef typename Iter::pointer pointer;
?typedef typename Iter::reference reference;
};
?