AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

直接cmp还是重载运算符

作者: 作者的头像   常台盘の超炮 ,  2024-05-05 19:37:24 ,  所有人可见 ,  阅读 12


0


题目是408机试第一题
那题我写的记录上也记录了很多容易写错的地方

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;
//忘记写这个了
const int N=1010;

typedef pair<string, int> PII;
//这里必须写成const的才能放到q[]里面去
PII q[N];

static bool cmp(PII a,PII b){



    return a.second < b.second;

}


static bool re(PII a,PII b){



    return a.second > b.second;

}

int n,m;

int main(){
cin>>n>>m;
for(int i=0;i<n;i++) cin>>q[i].first>>q[i].second;
if(m) stable_sort(q,q+n,cmp);
//自己打的时候发现stable_sort不会用,反正第三个参数从小到大不用写,从大到小就写greater<>(),其中泛型写那个结构体的类名
else stable_sort(q,q+n,re);
for(int i=0;i<n;i++) cout<<q[i].first<<" "<<q[i].second<<endl;
return 0;
}

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;
//忘记写这个了
const int N=1010;

typedef pair<int, int> PII;
//这里必须写成const的才能放到q[]里面去
struct Person{
string name;
int num;

bool operator< (const Person& t) const{

    return num<t.num;   

}

 bool operator> (const Person& t) const{

    return num>t.num;

}

}q[N];

int n,m;

int main(){
cin>>n>>m;
for(int i=0;i<n;i++) cin>>q[i].name>>q[i].num;
if(m) stable_sort(q,q+n);
//自己打的时候发现stable_sort不会用,反正第三个参数从小到大不用写,从大到小就写greater<>(),其中泛型写那个结构体的类名
else stable_sort(q,q+n,greater<Person>());
for(int i=0;i<n;i++) cout<<q[i].name<<" "<<q[i].num<<endl;
return 0;
}

不同点
第一段代码

使用pair<string, int>:将姓名和数值封装为pair类型,这样可以直接利用pair的比较操作符重载,通过自定义的比较函数cmp和re来实现升序或降序排序。
自定义比较函数:定义了两个静态函数cmp和re作为排序准则,分别用于升序和降序排列。这种做法在需要更复杂比较逻辑时较为灵活。

第二段代码

使用结构体Person:定义了一个结构体Person来存储姓名和数值,相比pair,结构体可以提供更多灵活性,比如可以添加更多成员或方法。
重载比较运算符:在Person结构体内重载了<和>运算符,这使得可以直接使用默认的排序规则或者通过greater<Person>()来改变排序方向,代码看起来更加直观且结构清晰。

总结

第一种直接用pair作为自定义类型,装入数组,sort的逻辑写在cmp中,cmp要自己写
也就是说pair自定义类型和排序逻辑cmp是分开的

第二种自定义类型用的struct,然后在struct里面重载运算符,默认排序的时候不用加cmp,
反过来排序就用greater<struct名字>()即可
注意重载运载符的使用规则
只需要升序排序,那么只需要定义<运算符。如果还需要降序排序,那么定义>运算符
是必要的。

ps:如果你选择了重载运算符的做法,但是又要反向排序,你会用到greater<struct>()
可能你会想这个东西不还是cmp吗,那重载运算符还有必要吗?
其实可以这么说,如果你只需要从小到大排序,你只用<
从大到小排序,你还的>并且搭配greater

–当然了,你就算只用<,也能实现从大到小的排序的逻辑
但是,我们这里谈的是同时实现从小到大,从大到小就借助greater
只实现一种当然随便实现了。–不行,事实证明,不那么写
编译器直接报错

gpt回答
是的,即使你只保留了带有greater<Person>()的stable_sort调用:

stable_sort(q, q+n, greater<Person>());

你也仍然需要重载运算符。在这个场景中,虽然你没有直接使用自定义的<运算符,但greater<Person>()比较器内部可能会用到它。greater是一个比较函数对象,它通常通过调用对象的<运算符来判断第二个对象是否大于第一个对象。因此,为了确保greater<Person>()能正确工作,你的Person结构体中重载的>运算符是必要的。不过,严格来说,对于使用greater的情况,重载>运算符已经足够,因为greater实际上会转换为使用>逻辑来进行比较。

简而言之,如果你的代码中存在任何排序调用,并且这些调用依赖于对象之间的比较,那么相应的比较运算符(在这个案例中是<或>)就需要被重载以提供正确的比较逻辑。

这里额外再提一下,cmp不止用在sort这里,优先队列也有用
目前看来,优先队列的排序或者说是堆,排序只有cmp,没有重载运算符

0 评论

App 内打开
你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息