Iterator和反向迭代器之间的区别

时间:2013-01-18 19:02:26

标签: c++ algorithm stl comparison stable-sort

以下两个代码段之间有什么区别。

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问题AC提供了XMAXACWA之间的唯一区别是使用的sort()版本。

6 个答案:

答案 0 :(得分:7)

两个函数调用 NOT 给出相同的答案,因为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

上的输出

答案 1 :(得分:3)

反向迭代器在正常迭代器的反方向上进行简单迭代。

因此,两个片段都会按升序排序[first,last]范围内的所有内容。 区别在于它将首先使用&lt;运算符用于比较,在第二个用于给定函数。

详细说明第一个实际上是按非升序排序,但由于你也反过来比较,它会再次反转,这会中和效果。

注意:相互比较的元素不能保证保持原始的相对顺序。

有用的参考资料:std::sortstd::vector::beginstd::vector::endstd::vector::rbeginstd::vector::rend

答案 2 :(得分:1)

顾名思义,反向迭代器以相反的顺序访问集合。如果您要求STL sort()算法对从a.begin()a.end()的范围进行排序,则会将结果值放在... a.begin()到{{1}的范围内},按照那些迭代器定义的顺序。

那么如果你要求它将范围从a.end()排序到a.rbegin()会怎样?它按照那些迭代器定义的顺序将结果放在...... a.rend()a.rbegin()的范围内。

答案 3 :(得分:0)

rbegin为您提供一个指向列表末尾的迭代器,并在您要求它向前移动时向后移动。同样,rend为您提供了列表开头的迭代器。

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

此处的第三个参数用于定义您自己的排序顺序。如果未指定,则将使用该对象的默认值。

答案 4 :(得分:0)

他们都完成了同样的事情。在第一个版本中,您反转迭代器的顺序以获得从高到低的排序。在第二个版本中,您可以改变比较的感觉,也可以进行从高到低的排序。

答案 5 :(得分:0)

迭代器从头到尾运行,反向迭代器从最后一个到第一个运行。所以sort(a.begin(), a.end())按顺序将元素放在[first,last]范围内; sort(a.rbegin(), a.rend())按顺序将元素放在[last,first]范围内,从而产生与第一个版本相反的顺序。