簡體   English   中英

迭代器和反向迭代器之間的區別

[英]Difference between Iterator and reverse iterator

以下兩個代碼段之間有什么區別?

vector<int> a;
// initialization code
sort( a.rbegin(), a.rend() );

vector<int> a;
// same initialization as above
sort(a.begin(), a.end(), comp);

其中comp是下面給出的布爾函數

bool comp( int i, int j)
{
    return i>j;
}

為了說明,下面的代碼給出WA,而此代碼給出SPOJ問題XMAX的 AC ACWA之間的唯一區別是使用的sort()版本。

這兩個函數調用不會給出相同的答案,因為std::sort 不是穩定的算法 ,即它不會在它們的相對順序中保留相同的元素。 在下面的示例中, std::pair<int, int>的元素在其第一個元素上排序。 使用反向比較功能以反向順序進行排序和排序不會產生相同的序列。 std::stable_sort相同操作會產生相同的結果。

#include <algorithm>
#include <iostream>
#include <ios>
#include <vector>

int main()
{
    typedef std::pair<int, int> Element;
    std::vector<Element> v;

    v.push_back( Element(1,1) );
    v.push_back( Element(-1,1) );
    v.push_back( Element(1,2) );
    v.push_back( Element(-1,2) );
    v.push_back( Element(1,3) );
    v.push_back( Element(-1,3) );
    v.push_back( Element(1,4) );
    v.push_back( Element(-1,4) );
    v.push_back( Element(1,5) );
    v.push_back( Element(-1,5) );
    v.push_back( Element(1,6) );
    v.push_back( Element(-1,6) );
    v.push_back( Element(1,16) );
    v.push_back( Element(-1,16) );
    v.push_back( Element(1,22) );
    v.push_back( Element(-1,22) );
    v.push_back( Element(1,33) );
    v.push_back( Element(-1,33) );
    v.push_back( Element(1,44) );
    v.push_back( Element(-1,44) );
    v.push_back( Element(1,55) );
    v.push_back( Element(-1,55) );
    v.push_back( Element(1,66) );
    v.push_back( Element(-1,66) );

    for (auto it = v.begin(); it != v.end(); ++it) {
        std::cout << "(" << it->first << "," << it->second << ")" << " ";
    }
    std::cout << "\n";

    auto w1 = v;
    std::sort(w1.begin(), w1.end(), [](Element const& e1, Element const& e2){ 
       return e1.first < e2. first;
    });
    auto w2 = v;
    std::sort(w2.rbegin(), w2.rend(), [](Element const& e1, Element const& e2) {
       return e1.first > e2.first;
    });
    std::cout << std::boolalpha << std::equal(w1.begin(), w1.end(), w2.begin()) << "\n";

    auto w3 = v;
    std::stable_sort(w3.begin(), w3.end(), [](Element const& e1, Element const& e2){ 
       return e1.first < e2. first;
    });
    auto w4 = v;
    std::stable_sort(w4.rbegin(), w4.rend(), [](Element const& e1, Element const& e2) {
       return e1.first > e2.first;
    });
    std::cout << std::boolalpha << std::equal(w3.begin(), w3.end(), w4.begin()) << "\n";

}

LiveWorkSpace上輸出

反向迭代器簡單地沿正常迭代器的反向迭代。

因此,兩個摘要都將按升序對[first,last]范圍內的所有內容進行排序。 區別在於,第一個將使用<運算符進行比較,第二個則使用給定的函數。

詳細地說,第一個實際上是以非升序排序的,但是由於您也反轉了比較,所以它又被反轉了,從而抵消了影響。

注意:相互比較的元素不保證保持其原始相對順序。

有用的參考: std::sortstd::vector::beginstd::vector::endstd::vector::rbeginstd::vector::rend

顧名思義,反向迭代器以相反的順序訪問集合。 如果您要求STL sort()算法對從a.begin()a.end()的范圍進行排序,則會將結果值放在...從a.begin()a.end()的范圍內,按照這些迭代器定義的順序。

那么,如果您要求它對從a.rbegin()a.rend()的范圍進行排序,會發生什么? 它將結果放置在...范圍內,從a.rbegin()a.rend() ,由這些迭代器定義的順序。

rbegin為您提供了一個迭代器,該迭代器指向列表的末尾,並在您要求其向前移動時向后移動。 同樣, rend為您提供一個到列表開頭的迭代器。

sort(a.begin(), a.end(), comp);

這里的第三個參數用於定義您自己的排序順序。 如果未指定,則將使用該對象的默認值。

他們倆都完成同一件事。 在第一個版本中,您可以顛倒迭代器的順序以獲得從高到低的排序。 在第二個版本中,您顛倒了比較的感覺,也得到了從高到低的排序。

迭代器從頭到尾運行,反向迭代器從頭到尾運行。 因此sort(a.begin(), a.end())將元素按順序排列在[first,last)范圍內; sort(a.rbegin(), a.rend())將元素放在[last,first)范圍內,順序與第一個版本相反。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM