代码改变世界

C++关联式容器的排序准则

2015-03-26 23:55  rangers  阅读(1142)  评论(0编辑  收藏  举报

stl中set和map为关联式容器,会根据排序准将元素自动排序。原型如下:

template<class _Kty,
	class _Pr = less<_Kty>,
	class _Alloc = allocator<_Kty> >
class set

template<class _Kty,
	class _Ty,
	class _Pr = less<_Kty>,
	class _Alloc = allocator<pair<const _Kty, _Ty> > >
class map

默认的排序准则为less<_Kty> 即通过 operator<对元素进行排序。所以如果set里存储的元素或map的key值为自定义的数据类型,必须要重载operator<。

当容器中存储的类型为别人设计,自己无法修改时,则通过自定义排序准则来实现关联式容器的排序功能。

//IntSet默认按less<int> 由小到大排序
typedef set<int> IntSet;

//自定义比较器实现由大到小排序
template <typename T> struct ReverseCmp
{
	bool operator()(const T & t1, const T & t2)
	{
		return t2 < t1;
	}
};

typedef set<int, ReverseCmp<int> > ReverseIntSet;

最近项目中的一个例子,map<string,int> StrMap 实现该map的key值 string不区分大小写,即StrMap["abc"] 与StrMap["Abc"]为同一元素。

实现如下:

//比较器实现
struct NoCaseCompare
{
	bool operator()(const string & str1, const string & str2)
	{
		string upper_str1(str1);
		string upper_str2(str2);
		std::transform(upper_str1.begin(),upper_str1.end(),upper_str1.begin(),toupper);
		std::transform(upper_str2.begin(),upper_str2.end(),upper_str2.begin(),toupper);
		return upper_str1.compare(upper_str2) >= 0 ? false : true;
	}
};

typedef map<string, int,NoCaseCompare> StrMap;

测试代码如下:

StrMap TestMap;
TestMap["aBc"] = 1;
TestMap["Cde"] = 2;
StrMap::iterator it;
it = TestMap.find("ABC");
if (it != TestMap.end())
{
  cout << "Key:" << (it->first).c_str() << "	value:" << it->second << "\n";
}

运行结果:

Key:aBc value:1