C++中的排序和踢重


在我接触到C++程序中,对于需要排序和踢重的操作,一般都是通过stl的map和set来实现的,对于简单的数据类型,比如说int和long等,由于可以直接比较大小,所以可以直接作为map的键和set的值,而对于class类型的数据,则不能直接作为map的键和set的值,需要对小于号的操作符进行重载。stl中的string也是数据class类型的数据,stl本身重载了小于号,这点可以从stl的源码中查看:

  // operator <
  /**
  *  @brief  Test if string precedes string.
  *  @param lhs  First string.
  *  @param rhs  Second string.
  *  @return  True if @a lhs precedes @a rhs.  False otherwise.
  */
  template<typename _CharT, typename _Traits, typename _Alloc>
    inline bool
    operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
              const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    { return __lhs.compare(__rhs) < 0; }

  /**
  *  @brief  Test if string precedes C string.
  *  @param lhs  String.
  *  @param rhs  C string.
  *  @return  True if @a lhs precedes @a rhs.  False otherwise.
  */
  template<typename _CharT, typename _Traits, typename _Alloc>
    inline bool
    operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
              const _CharT* __rhs)
    { return __lhs.compare(__rhs) < 0; }

  /**
  *  @brief  Test if C string precedes string.
  *  @param lhs  C string.
  *  @param rhs  String.
  *  @return  True if @a lhs precedes @a rhs.  False otherwise.
  */
  template<typename _CharT, typename _Traits, typename _Alloc>
    inline bool
    operator<(const _CharT* __lhs,
              const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    { return __rhs.compare(__lhs) > 0; }

compare的方法可以参考http://www.cplusplus.com/reference/string/string/compare/上面的解释
对于自定义类型的class,需要自己重载小于号,下面是一个例子:

#include<iostream>
#include<string>
#include<map>

using namespace std;

template<class Key, class Value>
inline ostream& operator<<(ostream& str, const map<Key, Value>& data)
{
    str << "{\n\t";
    typedef typename map<Key, Value>::const_iterator ConstIterator;
    for(ConstIterator iter = data.begin(); iter != data.end(); ++iter)
    {
        ConstIterator iterTmp = iter;
        iterTmp++;
        if(iterTmp == data.end())
        {
            str << *iter << "\n";
        }
        else
        {
            str << *iter << "\n\t";
        }
    }
    return str << "}";
}

template<class Key, class Value>
inline ostream& operator<<(ostream& str, const pair<Key, Value>& data)
{
    return str << "[key = " << data.first << "," << "value = " << data.second << "]";
}

class CTest
{
public:
    CTest(){}
    ~CTest(){}

    bool operator <(const CTest& cTest) const
    {
#ifdef POS
        return m_iSize < cTest.get_size();
#endif
        return m_iSize > cTest.get_size();
    }

public:
    inline int get_size() const
    {
        return m_iSize;
    }

    inline void set_size(const int & iSize)
    {
        m_iSize = iSize;
    }

private:
    int m_iSize;
};

inline ostream& operator<<(ostream& str, const CTest& data)
{
    return str << "[size = " << data.get_size() << "]";
}

int main(int args,char* argvs[])
{
    map<string,string> mapStr;
    mapStr.insert(make_pair("ab","ab"));
    mapStr.insert(make_pair("1","1"));
    mapStr.insert(make_pair("2","2"));
    mapStr.insert(make_pair("abc","abc"));
    mapStr.insert(make_pair("aba","aba"));

    map<CTest,string> mapClass;
    CTest cTest1;
    CTest cTest2;
    cTest1.set_size(1);
    cTest2.set_size(2);
    mapClass.insert(make_pair(cTest1,"1"));
    mapClass.insert(make_pair(cTest2,"2"));

    cout << mapStr << endl;
    cout << mapClass << endl;
}

  如果编译命令为:g++ testmap.cpp -DPOS -o testmap -g
  此时对于CTest排序使用的从小到大,结果如下:

{
        [key = 1,value = 1]
        [key = 2,value = 2]
        [key = ab,value = ab]
        [key = aba,value = aba]
        [key = abc,value = abc]
}
{
        [key = [size = 1],value = 1]
        [key = [size = 2],value = 2]
}


如果编译命令为: g++ testmap.cpp -o testmap -g
此时对于CTest的排序使用的是从达到小,结果如下:

{
        [key = 1,value = 1]
        [key = 2,value = 2]
        [key = ab,value = ab]
        [key = aba,value = aba]
        [key = abc,value = abc]
}
{
        [key = [size = 2],value = 2]
        [key = [size = 1],value = 1]
}


下面是一个set的例子:
#include<iostream>
#include<string>
#include<set>

using namespace std;

/**
* 重载<< 用于输出
*/
template<class Data>
inline ostream& operator<<(ostream& str, const set<Data>& data)
{
    str << "{\n\t";
    typedef typename set<Data>::const_iterator ConstIterator;
    for(ConstIterator iter = data.begin(); iter != data.end(); ++iter)
    {
        ConstIterator iterTmp = iter;
        iterTmp++;
        if(iterTmp == data.end())
        {
            str << *iter << "\n";
        }
        else
        {
            str << *iter << "\n\t";
        }
    }
    return str << "}";
}

/**
* 测试类
*/
class CTest
{
public:
    CTest(){}
    ~CTest(){}

    bool operator <(const CTest& cTest) const
    {
#ifdef POS
        return m_iSize < cTest.get_size();
#endif
        return m_iSize > cTest.get_size();
    }

public:
    inline int get_size() const
    {
        return m_iSize;
    }

    inline void set_size(const int & iSize)
    {
        m_iSize = iSize;
    }

private:
    int m_iSize;
};

/**
* 重载<< 用于输出
*/
inline ostream& operator<<(ostream& str, const CTest& data)
{
    return str << "[size = " << data.get_size() << "]";
}

int main(int args,char* argvs[])
{
    set<string> setStr;
    setStr.insert("ab");
    setStr.insert("1");
    setStr.insert("2");
    setStr.insert("abc");
    setStr.insert("aba");

    set<CTest> setClass;
    CTest cTest1;
    CTest cTest2;
    cTest1.set_size(1);
    cTest2.set_size(2);
    setClass.insert(cTest1);
    setClass.insert(cTest2);

    set<int> setInt;
    setInt.insert(1);
    setInt.insert(2);
    setInt.insert(2);

    cout << setStr << endl;
    cout << setClass << endl;
    cout << setInt << endl;
}


如果编译命令为g++ testset.cpp -DPOS -o testset -g
输出的结果为:
{
        1
        2
        ab
        aba
        abc
}
{
        [size = 1]
        [size = 2]
}
{
        1
        2
}


如果编译命令为g++ testset.cpp -o testset -g
输出的结果为:
{
        1
        2
        ab
        aba
        abc
}
{
        [size = 2]
        [size = 1]
}
{
        1
        2
}


由这个例子可以看出,通过重载<的方式,可以直接对class类型的数据进行排序。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值