在我接触到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类型的数据进行排序。