2009-11-24 39 views
22

我試圖實現一些STL風格的排序算法。原型爲std::sort看起來是這樣的(從cplusplus.com):從一個前向迭代器獲得一個反向迭代器而不知道值類型

template <class RandomAccessIterator> 
void sort (RandomAccessIterator first, RandomAccessIterator last); 

的功能通常被稱爲像這樣(儘管容器類型可能有所不同):

std::vector<int> myVec; 
// Populate myVec 
std::sort(myVec.begin(), myVec.end()); 

我複製的std::sort的原型我自己的分類功能。要通過容器迭代進行排序,我做到以下幾點:

template <class RandomAccessIterator> 
void mySort(RandomAccessIterator first, RandomAccessIterator last) { 
    RandomAccessIterator iter; 
    for (iter = first; iter != last; ++iter) { 
    // Do stuff 
    } 
} 

很容易的。但是如果我想使用反向迭代器呢?這對於從兩端對容器進行分類的算法是很方便的,例如, cocktail sort

有沒有什麼辦法從作爲參數傳入的迭代器中獲得反向迭代器?如果我提前知道容器類型,我可以做這樣的事情:

template <class RandomAccessIterator> 
void mySort(RandomAccessIterator first, RandomAccessIterator last) { 
    std::vector<int>::reverse_iterator riter(last); 
    std::vector<int>::reverse_iterator rend(first); 
    for (; riter != rend; ++riter) { 
    // Do stuff 
    } 
}  

不幸的是,我知道容器類型。我真正需要做的是這樣的:

template <class RandomAccessIterator> 
void mySort(RandomAccessIterator first, RandomAccessIterator last) { 
    RandomAccessIterator riter = reverse_iterator(last); 
    RandomAccessIterator rend = reverse_iterator(begin); 
    for (; riter != rend; ++riter) { 
    // Do stuff 
    } 
} 

是否有某種方式來做到這一點,而無需在反向迭代器作爲額外的參數傳遞(這將解決這個問題,但做的函數原型不太直觀) ?

注意,我需要向前反向迭代器在我的實現,所以調用函數這樣

std::vector<int> myVec; 
// Populate myVec 
mySort(myVec.rbegin(), myVec.rend()); 

將無法​​正常工作。

回答

28

的STL具有std::reverse_iterator<Iterator>

template <class RandomAccessIterator> 
void mySort(RandomAccessIterator first, RandomAccessIterator last) 
{ 
    typedef std::reverse_iterator<RandomAccessIterator> RIter; 
    RIter riter(last); 
    RIter rend(first); 
    for (; riter != rend; ++riter) { 
    // Do stuff 
    } 
} 

一種important note

通知然而,當一個迭代 反轉時,反轉版本並 不指向同一元件在 範圍,而是前面的那個。 之所以如此,爲了 安排了一系列的過去,在尾部元件: 指向的範圍,相反,當過去的最末端 元素的迭代,是 更改爲指向最後元素 (未經過它)的範圍(如果 顛倒,這將是 是該範圍的第一個元素)。並且如果一個迭代中的範圍內 第一個元素是第一元素之前反轉, 反向迭代器指向 元件(這 將是 如果顛倒的範圍內過去最端部元件)。

+0

我看到這個在以前的文檔,但放棄了它,當我不能用'reverse_iterator的得到什麼'編譯。問題:我忘了添加'std ::'(doh!)謝謝你的回答! – ThisSuitIsBlackNot 2009-11-24 03:02:09

+0

'重要提示'確實很重要。 'riter'將物理地指向元素_after_ last(在前向迭代意義上)。然而,有些違反直覺的是,'* riter' _does_指向與'last'相同的元素。 – bobobobo 2013-03-02 17:33:44

+2

當您分配'riter'和'rend'時,您使用'reverse_iterator'。這是什麼?它是'std :: reverse_iterator'嗎?後者是一個類,你必須提供一個模板參數,所以代碼是無效的。或者它是由您定義的函數? – Spiros 2015-01-13 13:55:56

-5

查看reverse_iterator的base()方法。

+0

,讓你的前向迭代器(什麼這個問題是問_reverse_) – bobobobo 2013-03-02 17:31:52