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)文章
Qt數(shù)據(jù)庫(kù)應(yīng)用之實(shí)現(xiàn)csv文件轉(zhuǎn)xls
這篇文章主要為大家詳細(xì)介紹了如何利用Qt實(shí)現(xiàn)csv文件轉(zhuǎn)xls功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定參考價(jià)值,需要的可以了解一下2022-06-06
C語(yǔ)言中結(jié)構(gòu)體和共用體實(shí)例教程
這篇文章主要給大家介紹了關(guān)于C語(yǔ)言中結(jié)構(gòu)體和共用體的相關(guān)資料,結(jié)構(gòu)體是一種自定義的復(fù)合數(shù)據(jù)類型,共用體也叫聯(lián)合體,使幾個(gè)不同類型的變量共占一段內(nèi)存(相互覆蓋),需要的朋友可以參考下2021-06-06
C++ 的 format 和 vformat 函數(shù)示例詳解
傳統(tǒng)C庫(kù)的printf系列函數(shù)存在安全問(wèn)題,而C++推薦的基于流格式化輸入輸出雖然解決了安全性問(wèn)題,但在易用性方面仍顯不足,C++11引入了新的C風(fēng)格字符串格式化函數(shù),但類型安全問(wèn)題依舊存在,下面通過(guò)本文介紹C++ 的 format 和 vformat 函數(shù)示例,感興趣的朋友一起看看吧2025-02-02
C++原地刪除有序數(shù)組重復(fù)項(xiàng)的N種方法
給定一個(gè)排序數(shù)組,你需要在原地刪除重復(fù)出現(xiàn)的元素,使得每個(gè)元素只出現(xiàn)一次,返回移除后數(shù)組的新長(zhǎng)度,不要使用額外的數(shù)組空間,你必須在 原地 修改輸入數(shù)組 并在使用O(1)額外空間的條件下完成,故本文介紹了C++原地刪除有序數(shù)組重復(fù)項(xiàng)的N種方法,需要的朋友可以參考下2025-03-03
C++實(shí)現(xiàn)LeetCode(50.求x的n次方)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(50.求x的n次方),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07

