如何在c++中使用STL关联式容器自定义排序规则

  介绍

如何在c++中使用STL关联式容器自定义排序规则?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

1)使用函数对象自定义排序规则

# include  & lt; iostream>   # include  & lt; set>,,//设置   # include  & lt; string>,,//字符串   using  namespace 性传播疾病;//定义函数对象类   class  cmp  {   公众:   ,//重载,(),运算符   ,bool  operator  () (const  string 和一个const  string , b), {//按才能照字符串的长度,做升序排序(即存储的字符串从短到长)   return 才能;(a.length (), & lt;, b.length ());   ,}   };   int  main (), {   ,//创建,set 容器,并使用自定义的,cmp 排序规则   ,std:: set<字符串,cmp> myset {“http://jb51.net.net/stl/"   ,,,,,,,,http://jb51.net.net/python/"   ,,,,,,,,http://jb51.net.net/java/"};   ,//输出容器中存储的元素   ,for  (auto  iter =, myset.begin ();, iter  !=, myset.end ();, + + iter), {   ,,cout  & lt; & lt;, * iter  & lt; & lt;, endl;   ,}   ,return  0;   }

程序执行结果为:
http://jb51.net.net/stl/
http://jb51.net.net/java/http://jb51.net.net/python/

重点分析一下6 ~ 13行代码,其定义了一个函数对象类,并在其重载()运算符的方法中自定义了新的排序规则,即按照字符串的长度做升序排序。在此基础上,程序第17行代码中,通过将函数对象类的类名cmp通过集类模板的第2个参数传递给myset容器,该容器内部排序数据的规则,就改为了以字符串的长度为标准做升序排序。
需要注意的是,此程序中创建的myset容器,由于是以字符串的长度为准进行排序,因此其无法存储相同长度的多个字符串。

另外,c++中的结构体和类非常类似(有关两者区别,可阅读《c++结构体和类到底有什么区别》一文),前者也可以包含成员变量和成员函数。因此上面程序中,函数对象类cmp也可以使用结构体关键字创建:

//定义函数对象类   struct  cmp  {   ,//重载,(),运算符   ,bool  operator  () (const  string ,,, const  string , b), {//按才能照字符串的长度,做升序排序(即存储的字符串从短到长)   return 才能;(a.length (), & lt;, b.length ());   ,}   };

值得一提的是,在定义函数对象类时,也可以将其定义为模板类。比如:

//定义函数对象模板类   template  & lt; typename  T>   class  cmp  {   公众:   ,//重载,(),运算符   ,bool  operator  () (const  T ,,, const  T , b), {//按才能照值的大小,做升序排序   return 才能a  & lt;, b;   ,}   };

注意,此方式必须保证T类型元素可以直接使用关系运算符(比如这里的& lt;运算符)做比较。

2)重载关系运算符实现自定义排序

其实在STL标准库中,本就包含几个可供关联式容器使用的排序规则,如表1表示。

表1 c++ STL标准库适用于关联式容器的排序规则

排序规则功能std:: less,,底层采用& lt;运算符实现升序排序,各关联式容器默认采用的排序规则. std:: greater底层采用比;运算符实现降序排序,同样适用于各个关联式容器. std:: less_equal底层采用& lt;=运算符实现升序排序,多用于多重映射和多重集容器. std:: greater_equal底层采用祝辞=运算符实现降序排序,多用于多重映射和多重集容器。

值得一提的是,表1中的这些排序规则,其底层也是采用函数对象的方式实现的。以std:: less为例,其底层实现为:

template  & lt; typename  T>   struct  less  {   ,//定义新的排序规则   ,bool 操作符()(const  T 和_lhs, const  T , _rhs), const  {   return 才能_lhs  & lt;, _rhs;   ,}   }

在此基础上,当关联式容器中存储的数据类型为自定义的结构体变量或者类对象时,通过对现有排序规则中所用的关系运算符进行重载,也能实现自定义排序规则的目的。

注意,当关联式容器中存储的元素类型为结构体指针变量或者类的指针对象时,只能使用函数对象的方式自定义排序规则,此方法不再适用。

举个例子:

# include  & lt; iostream>   # include  & lt; set>,,//设置   # include  & lt; string>,,//字符串   using  namespace 性传播疾病;//自定义类   class  myString  {   公众:   ,//定义构造函数,向,myset 容器中添加元素时会用的到   ,myString (string  tempStr),: str (tempStr), {};   ,//获取,str 私有对象,由于会被私有对象调用,因此该成员方法也必须为,const 类型   ,string  getStr(),常量;   私人:   ,string  str;   };   string  myString:: getStr (), const {   ,return 这→str;   }//重载,& lt;,运算符,参数必须都为,const 类型   bool  operator  & lt; (const  myString 和箍,,const  myString ,, strb), {   ,//以字符串的长度为标准比较大小   ,return  stra.getStr () . length (), & lt;, strb.getStr () . length ();   }   int  main (), {   ,//创建空,set 容器,仍使用默认的,less

如何在c++中使用STL关联式容器自定义排序规则