C++之set自定義排序問(wèn)題
set簡(jiǎn)介
set一般插入元素時(shí),默認(rèn)使用關(guān)鍵字類型的<
運(yùn)算符來(lái)比較兩個(gè)關(guān)鍵字,
故一般插入后為升序,但是針對(duì)自定義數(shù)據(jù)結(jié)構(gòu),
如結(jié)構(gòu)體,沒(méi)有<
運(yùn)算符,故無(wú)法進(jìn)行比較。
針對(duì)自定義數(shù)據(jù)結(jié)構(gòu)或者說(shuō)自定義set排序規(guī)則有如下幾種方法:
方法一 重載<
在自定義結(jié)構(gòu)體中重載<
則可以實(shí)現(xiàn)默認(rèn)排序,
示例代碼如下:
#include<iostream> #include<set> using namespace std; struct Students { string id; int age,height; Students(string s,int a,int h):id(s),age(a),height(h){} Students() {} bool operator <(const Students &s) const { if(id!=s.id) return id<s.id; else return age<s.age; } }; int main(){ set<Students> se; se.insert(Students("zhou",12,134)); se.insert(Students("wu",13,42)); se.insert(Students("zheng",34,43)); se.emplace("wang",13,43); se.emplace("zhou",23,43); for(auto it=se.begin();it!=se.end();it++){ cout<<it->id<<" "<<it->age<<" "<<it->height<<endl; } return 0; }
運(yùn)行結(jié)果如下:
方法二 重載()
示例代碼如下:
#include<iostream> #include<set> using namespace std; struct Students { string id; int age,height; Students(string s,int a,int h):id(s),age(a),height(h){} Students() {} }; class comp{ public: bool operator()(const Students &s1,const Students &s2){ if(s1.id!=s2.id) return s1.id<s2.id; return s1.age<s2.age; } }; int main(){ set<Students,comp> se; se.insert(Students("zhou",12,134)); se.insert(Students("wu",13,42)); se.insert(Students("zheng",34,43)); se.emplace("wang",13,43); se.emplace("zhou",23,43); for(auto it=se.begin();it!=se.end();it++){ cout<<it->id<<" "<<it->age<<" "<<it->height<<endl; } return 0; }
方法三 參考《C++ primer(第五版)》
示例代碼如下:
#include<iostream> #include<set> using namespace std; struct Students { string id; int age,height; Students(string s,int a,int h):id(s),age(a),height(h){} Students() {} }; bool cmp(const Students &s1,const Students &s2){ if(s1.id!=s2.id) return s1.id<s2.id; return s1.age<s2.age; } int main(){ set<Students,decltype(cmp)*> se(cmp); se.insert(Students("zhou",12,134)); se.insert(Students("wu",13,42)); se.insert(Students("zheng",34,43)); se.emplace("wang",13,43); se.emplace("zhou",23,43); for(auto it=se.begin();it!=se.end();it++){ cout<<it->id<<" "<<it->age<<" "<<it->height<<endl; } return 0; }
上述代碼中,用decltype
來(lái)指出自定義操作的類型。
當(dāng)使用decltype
來(lái)獲得一個(gè)函數(shù)指針類型時(shí),必須加上一個(gè)*
來(lái)指出我們要使用一個(gè)給定函數(shù)類型的指針。
用cmp
來(lái)初始化se
對(duì)象,這表示當(dāng)我們向se
中插入元素時(shí),通過(guò)調(diào)用cmp
來(lái)為這些元素排序。
可以使用cmp
代替&cmp
作為構(gòu)造函數(shù)的參數(shù),因?yàn)楫?dāng)我們使用一個(gè)函數(shù)的名字時(shí),在需要的情況下會(huì)自動(dòng)轉(zhuǎn)化為一個(gè)指針,使用&cmp
效果也是一樣的。
insert 和 emplace 的使用
emplace
對(duì)應(yīng)insert
,emplace_back
對(duì)應(yīng)于push_back
;
但是insert
和push_back
是直接將對(duì)象拷貝至容器當(dāng)中,而emplace
和emplace_back
是先調(diào)用存儲(chǔ)對(duì)象構(gòu)造函數(shù),在內(nèi)存中生成對(duì)象,然后拷貝至容器中。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C++采用openfilename打開文件對(duì)話框用法實(shí)例
這篇文章主要介紹了C++采用openfilename打開文件對(duì)話框用法實(shí)例,是C++文件操作中非常實(shí)用的技巧,需要的朋友可以參考下2014-10-10c語(yǔ)言實(shí)現(xiàn)從源文件從文本到可執(zhí)行文件經(jīng)歷的過(guò)程
這篇文章主要介紹了c語(yǔ)言實(shí)現(xiàn)從源文件從文本到可執(zhí)行文件經(jīng)歷的過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07使用C++實(shí)現(xiàn)簡(jiǎn)單的文章生成器
這篇文章主要為大家詳細(xì)介紹了鵝湖使用C++實(shí)現(xiàn)簡(jiǎn)單的狗屁不通文章生成器,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以了解下2024-03-03C++基本用法實(shí)踐之移動(dòng)語(yǔ)義詳解
移動(dòng)(move)語(yǔ)義是C++引入了一種新的內(nèi)存優(yōu)化,以避免不必要的拷貝,下面小編就來(lái)和大家簡(jiǎn)單聊聊C++中移動(dòng)語(yǔ)義的相關(guān)使用吧,希望對(duì)大家有所幫助2023-07-07C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之順序數(shù)組的實(shí)現(xiàn)
這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之順序數(shù)組的實(shí)現(xiàn)的相關(guān)資料,這里提供實(shí)現(xiàn)實(shí)例,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-08-08C++ OpenCV實(shí)現(xiàn)圖像去水印功能
本文將介紹如何使用OpenCV C++ 進(jìn)行簡(jiǎn)單圖像水印去除。我們?cè)诰W(wǎng)上download圖片時(shí),經(jīng)常因?yàn)榘鏅?quán)問(wèn)題有水印。本案例通過(guò)編寫算法進(jìn)行簡(jiǎn)單水印去除。需要的可以參考一下2022-01-01Linux下控制(統(tǒng)計(jì))文件的生成的C代碼實(shí)現(xiàn)
這篇文章主要介紹了Linux下控制(統(tǒng)計(jì))文件的生成的C代碼實(shí)現(xiàn),感興趣的小伙伴們可以參考一下2016-01-01