STL反向迭代器与STL排序

STL反向迭代器,其指向的值是正确的,但是其在调试时,该迭代器总是指向下一个(右侧)。

这是由于STL容器半闭半开区间(左闭右开)造成的。

rpos总是指向pos的前一个值,为什么呢?候捷先生译的《C++标准模板库》里是这么解释的:“注意,这不是bug,这是特性!导致这个行为的原因是区间的半开性。为了能够指定容器内所有元素,我们必须运用‘最后一个元素的下一位置’。”“逆向迭代器的设计者运用了一个小技巧:他们实际上倒置了‘半开原则’”

这两句话非常重要,首先容器的区间是左闭右开的,区间是以一个空位置作为区间的结束。对于逆向迭代器言,这个空位置就成了开始rbegin()的位置。但是这个位置上是没有值的,因此rbegin的值就取的是该位置前的一个值。--这正是“运用的小技巧”。这个小技巧保持了“以一个空位置作为区间结束”的原则。

(以上文字摘自: http://www.cnblogs.com/onlyan/articles/2657803.html

 

void main()

{

    vector<int> iV;
    iV.push_back(9);
    iV.push_back(4);
    iV.push_back(5);
    iV.push_back(11);
    iV.push_back(0);

    sort(iV.begin(), iV.end());
    sort(iV.begin(), iV.end(), greater<int>()); //函数对象,需要functional支持

    vector<int>::iterator it = iV.begin();
    ++it;
    --it;
    it += 3;

    //itr本身的值是同iV.end()相等的(从其本身的值来看,该itr不指向任何值)。
    //但实际上其指向的值是0
    vector<int>::reverse_iterator itr = iV.rbegin(); 

    //itr2本身的值同iv.begin()相等(从其本身的值来看,该itr2指向index为0的元素,即11)。
    //但实际上其指向的值不存在
    vector<int>::reverse_iterator itr2 = iV.rend();

    ++itr;
    --itr2;

}

 

以下是各种排序

// testAlgorithm.cpp : 定义控制台应用程序的入口点。
//
// testBitset.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <list>
#include <set>
#include <map>

using namespace std;


bool greater_than(const int& i1, const int& i2)
{
    return i1 >= i2;
}

//
struct stru
{
    int iID;
    string strName;

    bool operator >= (const stru& ob)
    {
        return iID >= ob.iID;
    }
    bool operator <= (const stru& ob)
    {
        return iID <= ob.iID;
    }
    bool operator > (const stru& ob)
    {
        return iID > ob.iID;
    }
    bool operator < (const stru& ob)
    {
        return iID < ob.iID;
    }
    bool operator == (const stru& ob)
    {
        return iID == ob.iID;
    }

};

bool less_than_ID(const stru& ob1, const stru& ob2)
{
    return ob1.iID < ob2.iID;
}
bool greater_than_ID(const stru& ob1, const stru& ob2)
{
    return ob1.iID >= ob2.iID;
}

bool less_than_Name(const stru& ob1, const stru& ob2)
{
    return strcmp(ob1.strName.c_str(), ob2.strName.c_str()) <= 0; // ob1.strName <= ob2.strName
}
bool greater_than_Name(const stru& ob1, const stru& ob2)
{
    return strcmp(ob1.strName.c_str(), ob2.strName.c_str()) >= 0;// ob1.strName >= ob2.strName
}
/*
//
int _tmain(int argc, _TCHAR* argv[])
{   
    vector<int> iV;
    iV.push_back(9);
    iV.push_back(4);
    iV.push_back(5);
    iV.push_back(11);
    iV.push_back(0);

    sort(iV.begin(), iV.end());
    sort(iV.begin(), iV.end(), greater_than);
//

    vector<stru> sV;

    stru ob1 = {5, "abcd"};
    sV.push_back(ob1);

    stru ob2 = {4, "fcba"};
    sV.push_back(ob2);

    stru ob3 = {7, "eeee"};
    sV.push_back(ob3);

    stru ob4 = {0, "张先生"};
    sV.push_back(ob4);

//    sort(sV.begin(), sV.end()); //需要重载 >= <= > < == 共5个操作运行符。

//    sort(sV.begin(), sV.end(), greater_than_ID); //按ID降序
//    sort(sV.begin(), sV.end(), less_than_ID); //按ID升序

//    sort(sV.rbegin(), sV.rend(), less_than_ID); //从后向前 按ID升序


    sort(sV.begin(), sV.end(), less_than_Name); //按Name升序
    sort(sV.begin(), sV.end(), greater_than_Name); //按Name降序

 

    return 0;
}
*/
//以上方式效率较低,由于 less_than_*, greater_than_* 函数,需要多次调用(需要多次初始化和清理栈),
//而这些函数又不是内联函数,因此效率较低.
//替代方案如下,是采用类重载操作符,内联函数形式


//

class LessThanID
{
public:
    inline bool operator () (const stru& ob1, const stru& ob2)
    {
        return ob1.iID <= ob2.iID;
    }
};

class GreaterThanID
{
public:
    inline bool operator () (const stru& ob1, const stru& ob2)
    {
        return ob1.iID >= ob2.iID;
    }
};

class LessThanName
{
public:
    inline bool operator () (const stru& ob1, const stru& ob2)
    {
        return strcmp(ob1.strName.c_str(), ob2.strName.c_str()) <= 0; // ob1.strName <= ob2.strName
    }
};

class GreaterThanName
{
public:
    inline bool operator () (const stru& ob1, const stru& ob2)
    {
        return strcmp(ob1.strName.c_str(), ob2.strName.c_str()) >= 0; // ob1.strName >= ob2.strName
    }
};


int _tmain(int argc, _TCHAR* argv[])
{
    vector<int> iV;
    iV.push_back(9);
    iV.push_back(4);
    iV.push_back(5);
    iV.push_back(11);
    iV.push_back(0);

    sort(iV.begin(), iV.end());
    sort(iV.begin(), iV.end(), greater<int>()); //函数对象,需要functional支持

    vector<int>::iterator it = iV.begin();
    ++it;
    --it;
    it += 3;

    //itr本身的值是同iV.end()相等的(从其本身的值来看,该itr不指向任何值)。
    //但实际上其指向的值是0
    vector<int>::reverse_iterator itr = iV.rbegin(); 

    //itr2本身的值同iv.begin()相等(从其本身的值来看,该itr2指向index为0的元素,即11)。
    //但实际上其指向的值不存在
    vector<int>::reverse_iterator itr2 = iV.rend();

    ++itr;
    --itr2;

 

    list<int> iLst;
    iLst.insert(iLst.end(), 9);
    iLst.insert(iLst.end(), 4);
    iLst.insert(iLst.end(), 5);
    iLst.insert(iLst.end(), 11);
    list<int>::iterator itL = iLst.begin();
    ++itL;
    --itL;
    list<int>::reverse_iterator itLr = iLst.rbegin();
    list<int>::reverse_iterator itLr2 = iLst.rend();


    set<int> iS;
    iS.insert(9);
    iS.insert(4);
    iS.insert(5);
    iS.insert(11);
    set<int>::iterator itS = iS.begin();
    ++itS;
    --itS;
    advance(itS, 2);
    advance(itS, -2);

 

    map<int, string> mp;
    mp[9] = "abc";
    mp[4] = "def";
    mp[5] = "厅厅";
    mp[11] = "44123";
    map<int, string>::iterator itM = mp.begin();
    ++itM;
    --itM;
    itM = --mp.end();
    map<int, string>::reverse_iterator itMr = mp.rbegin();
    std::cout<<itMr->first<<endl;
    advance(itMr, 2); std::cout<<itMr->first<<endl;
    advance(itMr, -1);
    std::cout<<mp.rbegin()->first<<endl;

    //
    vector<stru> sV;

    stru ob1 = {5, "abcd"};
    sV.push_back(ob1);

    stru ob2 = {4, "fcba"};
    sV.push_back(ob2);

    stru ob3 = {7, "eeee"};
    sV.push_back(ob3);

    stru ob4 = {0, "张先生"};
    sV.push_back(ob4);

    // 以下使用自定义的函数对象进行排序
//    sort(sV.begin(), sV.end(), LessThanID());
//    sort(sV.begin(), sV.end(), GreaterThanID());

    GreaterThanName gtN;
    sort(sV.begin(), sV.end(), gtN);
    sort(sV.begin(), sV.end(), LessThanName());

 

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值