STL自定义排序准则
C++关于STL中sort()对struct排序的方法

C++关于STL中sort()对struct排序的⽅法 ⼀直没有系统去看过c++,因为懂得⼀些c的基本语法,在实际编程中⽤到c++,只能⽤到哪些看哪些,发现这样虽然能够完成⼤部分⼯作,但是有时候效率实在太低,⽐如说这节要讲的Std::sort()函数的使⽤,调了半天才调通。
开通c/c++序列博客是记录在使⽤c++中⼀些难题,避免以后重犯错,当然以后会尽量挤出时间来较系统学习下c++。
开发环境:QtCreator2.5.1+OpenCV2.4.3 ⾸先来看看std中的快速排序算法sort的使⽤⽅法: 这是⼀个带模板的函数,参数1和2表⽰需要排序的元素在随机迭代器的起始位置和结束位置,其迭代器指向的数据类型可以⾃⼰定义,常见的数据类型包括结构体,vector,类等都可以被使⽤。
参数comp是⽤来决定所采⽤的排序是升序还是逆序的,默认情况下是升序排列。
但是这种默认情况的优势是处理迭代器指向的元素为普通的数据类型,⽐如说整型,字符型等。
如果指向的数据类型为类或者结构体,然后使⽤该类或者结构体中的某个元素进⾏排序,这时候需要⾃⼰定义排序的重载符号”<”。
⽐如说在本次实验中该重载符号的定义为:复制代码代码如下:/*按照降序排列*/bool compare(const PAIR &x, const PAIR &y){return x.point_value > y.point_value;} 如果将comp定义为⼀个函数(⽹上好像很多都是⽤这种类似的函数),⽐如说该函数如下:复制代码代码如下:/*按照降序排列*/bool operator<(const PAIR &x, const PAIR &y){return x.point_value > y.point_value;} 则会报错如下错误: std::sort因为函数参数不明确,所以⽆法推导出模板参数等. 本次实验是基于这样⼀个问题的:有⼀些坐标点集合(2d的坐标点,坐标点之间没有重复),每个坐标点对应⼀个数,现在需要对这些数排序从⽽达到对这些坐标点排序。
stl排列组合函数

stl排列组合函数STL(Standard Template Library)是C++标准库中的一个重要组成部分。
它提供了一组通用的模板容器和算法,可以帮助程序员简化代码的编写。
其中,STL中的排列组合函数特别重要。
下面就来介绍一下STL中常用的排列组合函数。
一、排列排列是从n个元素中任选r个元素进行排列的方法总数,公式为 P(n,r) = n! /(n-r)!。
在STL中,可以使用next_permutation函数来求出n个元素中任选r个元素的所有排列。
```c++#include <iostream>#include <algorithm>using namespace std;sort(s.begin(), s.end());do {cout << s[0] << s[1] << endl;} while (next_permutation(s.begin(), s.end()) && s[1] != 'c');return 0;}```输出结果为:```Permutations of choosing 2 chars from "abc":abacbabccacb```这段代码中,首先将字符串“abc”按字典序从小到大排序,然后通过do-while循环,使用next_permutation函数来生成所有的排列。
需要注意的是,为了避免重复计算,这里限制了第二个字符不能等于字符‘c’。
二、组合下面是使用next_combination函数来求出0至9之间任意选择3个数的所有组合的代码:sort(v.begin(), v.end());do {int j = 0;for (int i = 0; i < v.size(); ++i) {if (comb[i]) {cout << v[i] << " ";++j;}if (j == 3) break;}cout << endl;} while (prev_permutation(comb.begin(), comb.end()));```Combinations of choosing 3 elements from {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}:0 1 20 1 30 1 40 1 50 1 60 1 70 1 80 1 90 2 30 2 40 2 50 2 6...```这段代码中,首先创建了一个包含0至9的vector,并且将任取3个数的组合表示成了一个01串。
C++STLpriority_queue自定义排序实现方法详解

C++STLpriority_queue⾃定义排序实现⽅法详解前⾯讲解 priority_queue 容器适配器时,还遗留⼀个问题,即当 <function> 头⽂件提供的排序⽅式(std::less<T> 和std::greater<T>)不再适⽤时,如何⾃定义⼀个满⾜需求的排序规则。
⾸先,⽆论 priority_queue 中存储的是基础数据类型(int、double 等),还是 string 类对象或者⾃定义的类对象,都可以使⽤函数对象的⽅式⾃定义排序规则。
例如:#include<iostream>#include<queue>using namespace std;//函数对象类template <typename T>class cmp{public://重载 () 运算符bool operator()(T a, T b){return a > b;}};int main(){int a[] = { 4,2,3,5,6 };priority_queue<int,vector<int>,cmp<int> > pq(a,a+5);while (!pq.empty()){cout << pq.top() << " ";pq.pop();}return 0;}运⾏结果为:2 3 4 5 6注意,C++ 中的 struct 和 class ⾮常类似,前者也可以包含成员变量和成员函数,因此上⾯程序中,函数对象类 cmp 也可以使⽤ struct 关键字创建:struct cmp{//重载 () 运算符bool operator()(T a, T b){return a > b;}};可以看到,通过在 cmp 类(结构体)重载的 () 运算符中⾃定义排序规则,并将其实例化后作为 priority_queue 模板的第 3 个参数传⼊,即可实现为 priority_queue 容器适配器⾃定义⽐较函数。
CSTL中Map的按Key排序和按Value排序

map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据k ey查到相应的val ue。
假如存储学生和其成绩(假定不存在重名,当然可以对重名加以区分),我们用map 来进行存储就是个不错的选择。
我们这样定义,map<string, int>,其中学生姓名用stri ng 类型,作为Key;该学生的成绩用int类型,作为valu e。
这样一来,我们可以根据学生姓名快速的查找到他的成绩。
但是,我们除了希望能够查询某个学生的成绩,或许还想看看整体的情况。
我们想把所有同学和他相应的成绩都输出来,并且按照我们想要的顺序进行输出:比如按照学生姓名的顺序进行输出,或者按照学生成绩的高低进行输出。
换句话说,我们希望能够对map进行按Key排序或按V alue排序,然后按序输出其键值对的内容。
一、C++ STL中Ma p的按Ke y排序其实,为了实现快速查找,map内部本身就是按序存储的(比如红黑树)。
在我们插入<key, value>键值对时,就会按照ke y的大小顺序进行存储。
这也是作为k ey的类型必须能够进行<运算比较的原因。
现在我们用s tring类型作为k ey,因此,我们的存储就是按学生姓名的字典排序储存的。
【参考代码】1.#includ e<map>2.#includ e<string>3.#includ e<iostre am>ingnamesp ace std;5.6.typede f pair<string, int> PAIR;7.8.ostrea m& operat or<<(ostrea m& out, constPAIR& p) {9.return out << p.first<< "\t" << p.second;10.}11.12.int main() {13. map<string, int> name_s core_map;14. name_s core_map["LiMin"] = 90;15. name_s core_map["ZiLinM i"] = 79;16. name_s core_map["BoB"] = 92;17. name_s core_map.insert(make_p air("Bing",99));18. name_s core_map.insert(make_p air("Albert",86));19.for (map<string, int>::iterat or iter = name_s core_map.begin();20. iter != name_s core_map.end();21. ++iter) {22. cout << *iter << endl;23. }24.return 0;25. }【运行结果】大家都知道m ap是st l里面的一个模板类,现在我们来看下map的定义:1.templa te < classKey, classT, classCompar e = less<Key>,2.classAlloca tor = alloca tor<pair<constKey,T> > > classmap;它有四个参数,其中我们比较熟悉的有两个: Key 和 Value。
STL全排序,部分排序等

排序一直是数据结构中的常用算法,STL提供的排序算法非常丰富,如何有效使用就值得探讨。
在网上没有找到条款31的翻译,于是我自己翻译了。
--Winter如何进行排序?让我数数有几种方法。
一旦程序员需对容器元素进行排序,sort算法马上就会出现在他的脑海(可能有些程序员会想到qsort,但详细阅读条款46后,他们会放弃使用qsort的想法,转而使用sort算法)。
sort是一个非常优秀的算法,但并当你并不真正需要它的时候,其实就是一种浪费。
有时你并不需要一个完整的排序(简称为全排序)。
例如,你现有一个包含Widget对象(Widget意为“小挂件”)的vector 容器,并且你想把其中质量最好的20个Widget送给你最好的客户,那么你需做的只是找出这20个质量最好的Widget元素,剩下的并不需关心它们的顺序。
这时你需要的是部分排序(相对于全排序),恰好在算法中就有一个名副其实的部分排序函数函数:partial_sort:bool qualityCompare(const Widget& lhs, const Widget& rhs){// lhs的质量不比rhs的质量差时返回true,否则返回false}…partial_sort (widgets.begin(), // 把质量最好的20元素widgets.begin() + 20, // 顺序放入widgets容器中widgets.end(),qualityCompare);… // 使用widgets...通过调用partial_sort,容器中开始的20个元素就是你需要的质量最好的20个Widget,并按顺序排列,质量排第一的就是widgets[0], 紧接着就是widgets[1],依次类推。
这样你就可以把质量第一的Widget送给你最好的顾客,质量第二的Widget就可以送给下一个顾客,很方便吧,更方便的还在后面呢。
如果你只是想把这20个质量最好的Widget礼物送给你最好的20位顾客,而不需要给他们一一对应,partial_sort在这里就有些显得大材小用了。
c++中STL容器中的排序

for (auto it = s2.cbegin(); it != s2.cend(); it++)
{
cout << *it << " ";
}
cout << endl;
system("pause");
return 0;
}
4.STL中map: 由于在map中是由红黑树实现的所以自带生序排序(key) #include <iostream> #include <map> #include <string> using namespace std; int main() { map <int,string,less<int> > map1;//使用less有小到大 greater由大到小 map1[1]="HZ"; map1[8]="yu"; map1[100]="rue"; map1[-10]="23"; map<int,string>::iterator cmap=map1.begin(); while(cmap!=map1.end()) {
cout<<*cset<<" "; cset++; } int m; cin>>m; return 0; }
若定义set中存储的为结构体:
#include <iostream> #include <string> #include <set> using namespace std;
C++STL标准库指南

C++ STL标准库指南C++ STL 标准库指南C++ STL(Standard Template Library)是一种重要的 C++ 库,它提供了一组通用的数据结构和算法工具,便于 C++ 程序员开发高效、稳定和可移植的代码。
STL 标准库由三个主要部分组成:容器、算法和迭代器。
容器容器是 STL 标准库的核心组成部分。
容器是存储数据的对象,它包括了各种数据结构,如数组、链表、向量、映射等。
C++ STL 标准库中提供了许多不同的容器类型,每个容器有其特定的使用场景和性能特征。
常见的容器类型包括:1. 向量(vector)向量是一个元素列表,支持随机访问的迭代器。
向量的大小可以动态调整,它会自动管理内存,可以高效地进行内存操作。
向量是一个非常常用的容器类型,可以用于存储单个类型的元素或自定义结构体。
2. 链表(list)链表是一个元素序列,每个元素都是由前一个元素和后一个元素组成的节点链。
链表不支持随机访问,但是支持高效插入和删除操作。
链表可以用于实现队列、栈等数据结构。
3. 映射(map)映射是一组键值对,每个键对应一个值。
映射中的键是唯一的,如果添加一个已经存在的键,则会替换对应的值。
映射提供了方便的查询和插入操作,可以用于实现字典、数据库等数据结构。
算法算法是 STL 标准库的另一个重要组成部分。
它提供了一组通用的算法,可以用于操作容器、迭代器以及其他数据类型。
STL 提供了大量的算法,包括排序、查找、字符串操作等,为开发高效的 C++ 程序提供了强大的工具支持。
常见的算法类型包括:1. 排序算法排序算法是一组重要的算法,可以用于对容器中的元素进行排序。
STL 标准库中提供了多种排序算法,包括快速排序、归并排序、堆排序等,可以根据不同的性能要求选择不同的算法。
2. 查找算法查找算法是一组用于在容器中查找元素的算法。
STL 标准库中提供了多种查找算法,包括二分查找、线性查找等,可以根据不同的复杂度和数据类型选择合适的算法。
stl常用算法

stl常用算法
STL(StandardTemplateLibrary)是C++的一种标准库,其中包含了许多常用的算法。
以下是STL中常用的算法:
1. sort:排序算法,可对数组或容器进行排序。
2. find:在容器中查找某个元素,返回该元素的迭代器。
3. count:统计容器中某个元素的个数。
4. max/min:返回容器中最大/最小元素的迭代器。
5. accumulate:对容器中的元素进行累加操作。
6. reverse:将容器中的元素反转。
7. unique:去重,将容器中重复的元素去除。
8. transform:对容器中的元素进行转换操作。
9. copy:将一个容器中的元素复制到另一个容器中。
10. fill:将容器中的元素全部赋值为指定值。
以上是STL中常用的算法,它们提供了一些方便的方法来操作容器中的元素。
在实际开发中,我们可以根据需要选择合适的算法来解决问题。
- 1 -。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
使用< 操作符指定set或multiset的排序准则,map和multimap也可以同样做法#include <vector>#include <iostream>#include <set>using namespace std;class T{private:int x;double y;public:T(int X, double Y){x = X;y = Y;}double getXY() const{return ((double)x + y);}bool operator< (T t) const{return (x + y) < t.getXY();}void print() const{cout << "x = " << x << " y = " << y << " x + y = " << getXY() << endl;}};int main(){T t1 = T(1, 3.2);T t2 = T(2, 1.1);T t3 = T(100,0.1);T t4 = T(1, 2.1);multiset<T> set_T;set_T.insert(t1);set_T.insert(t2);set_T.insert(t3);set_T.insert(t4);如:typedef int ID_CARDstruct Account{int id_account;int money;};typedef std::multimap<ID_CARD, Account *> AMap;上面这个结构体,我现在可以通过指定ID_CARD的值,找到对应的若干Account,现在我希望把找到的Account值按照money数目的多少排序,请问这个应该怎么利用multimap容器本身来实现?具体如下:AMap a;Account *a1 = new Account;Account *a2 = new Account;Account *a3 = new Account;Account *a4 = new Account;Account *a5 = new Account;......a.insert(make_pair(1, a1));a.insert(make_pair(1, a2));a.insert(make_pair(2, a3));...要得到某个ID_CARD对应的Account可以用:pair<AMap::iterator, AMap::iterator> account_range = a.equal_range(1);我现在希望把account_range中的值按照Account->money多少来排序,怎么实现?我以前在C++标准库那本书上看到过这种例子,现在又找不到了,请各位高手指点迷津!这个问题,恐怕不能解决吧,我也在看c++标准程序库,但是没有看到你说的这个问题的解决方法,不知道你是在什么地方看到的,我在自己设计map排序准则的时候好像不能通过map的value这个pir中的第二个值来作为排序的依据,我认为,可能是map的排序准则中的参数传递过程中,只把map成员中pir中第一个参数传入(即key)而第二个参数value 这个参数并没有传入,所以你指定的排序准则再完美也没有用,因为这根本就不找不到你要的第二个值,不知道老兄有没有找到解决的方法。
不不过,我在网上找的一个解决的办法,可以实现这个功能,就是通过vector 和sort这两个函数来完成的,因为,vector第一的时候是一个值,如果你保存在vector中的是一个结构体的话,他会把整个结构体当成参数传到你自定义的排序准则里面,这样你就可以根据你结构体的结构来指定排序规则了,不知道说了这么多能不能帮助你解决问题STL map中key为结构体的用法分类:ACM2012-11-01 12:10189人阅读评论(0)收藏举报最近在使用stl中的map容器时,碰到key为结构体的情况,总结如下,以便提醒自己。
我的使用情景是,我需要根据不同的比例尺、道路类型这两个参数获取到对应的道路宽度,由于我是使用map解决这个问题的,自然而然的就以比例尺、道路类型这两个参数为key,道路宽度为value,建立的key如下:1typedef struct tagRoadKey2{3int nType;4int nScale;5}6}ROADKEY;但是编译的时候,报了这个错误d:/program files/microsoft visual studio/vc98/include/functional(86) : error C2784: 'bool__cdecl std::operator <(const class std::multimap<_K,_Ty,_Pr,_A> &,const classstd::multimap<_K,_Ty,_Pr,_A> &)' : could not deduce template argument for 'constclass std::multimap<_K,_Ty,_Pr,_A> &' from 'const struct tagRoadKey'说实话,当初不太明白这是什么错误,但从个人经验来判断,问题肯定出在这个key上面,后来google下,看到了别人写的文章,才知道原因,原来map中的key默认是以less<>升序对元素排序(排序准则也可以修改),也就是说key必须具备operator<对元素排序,而平常我们的用的基本上都是基本类型元素作为key,所以就不存在这个问题了,更详细的解释请看C++标准程序库一书,第六章,set容器章节。
改正后的结构体如下:1typedef struct tagRoadKey2{3int nType;4int nScale;56booloperator<(const tagRoadKey& other)const7{8if(nType < other.nType)//类型按升序排序9{10returntrue;11}12elseif(nType == other.nType) //如果类型相同,按比例尺升序排序13{14return nScale < other.nScale;15}1617returnfalse;18}19}ROADKEY;完整代码如下:1//////////.h///////2#ifndef _CROADWIDTHMNG_H_3#define_CROADWIDTHMNG_H_4#include <map>56usingnamespace std;78/*9说明:根据当前比例尺、道路类型获取对应的道路宽度10*/11typedef struct tagRoadKey12{13int nType;14int nScale;1516booloperator<(const tagRoadKey& other)const17{18if(nType < other.nType)//类型按升序排序19{20returntrue;21}22elseif(nType == other.nType) //如果类型相同,按比例尺升序排序23{24return nScale < other.nScale;25}2627returnfalse;28}29}ROADKEY;3031struct tagRoadInfo32{33tagRoadKey roadKey;34int nRoadWidth;35};3637class CRoadWidthMng38{39public:40CRoadWidthMng();41virtual~CRoadWidthMng();4243public:44int GetRoadWidth(int nRoadType,int nScale); //根据道路类型、比例尺获取宽度4546private:47void Init();4849private:50constint MIN_SCALE; //最小的比例尺51const int DEFAULT_ROAD_WIDTH; //如没有找到,返回默认值5253map<ROADKEY, int>m_roadMap;54};5556#endif5758////////.cpp///////59#include "CRoadWidthMng.h"6061tagRoadInfo roadInfoItem[] =62{63///////////高速公路//////////////64{65{671268},691670},71{72{7310,741175},761277},7879{80{8110,821083},84685},86{87{8810,89990},91392},93///////国道///////////////// 94{95{9612,971298},9912100},102{10312,10411105},1068107},108109{110{11112,11210113},1146115},116{117{11812,1199120},1214122},123///////省道///////////////// 124{125{12614,12712128},12910130},131{132{13314,13411135},137},138139{140{14114,14210143},1446145},146{147{14814,1499150},1514152},153///////铁路///////////////// 154{155{15621,15712158},1591160},161{162{16321,16411165},1661167},168169{170{17210173},1741175},176{177{17821,1799180},1811182},183};184185CRoadWidthMng::CRoadWidthMng()186:MIN_SCALE(6), DEFAULT_ROAD_WIDTH(5)187{188Init();189}190191CRoadWidthMng::~CRoadWidthMng()192{193m_roadMap.clear();194}195196void CRoadWidthMng:: Init()197{198int nNum =sizeof(roadInfoItem) / sizeof(roadInfoItem[0]);199200for(int i = 0; i < nNum; ++i)201{202m_roadMap.insert(make_pair(roadInfoItem[i].roadKey, roadInfoItem[i].nRoadWidth)); 203}204}205206int CRoadWidthMng:: GetRoadWidth(int nRoadType,int nScale) 207{208if(nScale < MIN_SCALE)209{210nScale = MIN_SCALE;211}212213map<ROADKEY, int>::iterator itor;214215int nValue;216ROADKEY roadkey;217roadkey.nType = nRoadType;218roadkey.nScale = nScale;219220itor = m_roadMap.find(roadkey);221222if(itor != m_roadMap.end())223{224nValue = itor->second/*nRoadWidth*/;225}226else227{228nValue = DEFAULT_ROAD_WIDTH;229}230231return nValue;232}【转】容器C++ set和map转载地址:/volkswageos/article/details/6020744容器C++ set和mapset, multisetset和multiset会根据特定的排序准则自动将元素排序,set中元素不允许重复,multiset可以重复。