C++中的排序和踢重

来源:互联网 发布:抢报名的软件 编辑:程序博客网 时间:2024/05/19 16:20

在我接触到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
原创粉丝点击