C++代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n;
class Data //由于有语,数,英,学号,总分故这里用一个类更直观
{ // C++的类和结构体只有默认访问权限不同这一个区别,这里用结构体也行
public:
int C;
int M;
int E;
int Sum;
int Num;
Data(int C, int M, int E, int Num) //Data类的构造函数
:C(C),M(M),E(E),Num(Num) {this->Sum = C+M+E;}
};
vector<Data> A; // 用vector容器来保存每一个Data对象
int main()
{
cin >> n; // 输入学生的总数
for(int i = 0; i < n; ++i)
{
int a,b,c;
cin >> a >> b >> c;
A.emplace_back(a,b,c,i+1); //注意参四的学号传入时要 +1, 这里不用push_back防止拷贝
}
sort(A.begin(), A.end(), [](Data &A, Data &B) //用sort函数排序,包含头文件algorithm
{ // 由于是自定义类型,故不能直接用sort的默认参数,故这里参3需要我们自己实现排序规则
if(A.Sum != B.Sum) return A.Sum > B.Sum; // 注意这里的判断条件是
if(A.C != B.C) return A.C > B.C;
return A.Num < B.Num;
});
for_each(A.begin(), A.begin() + 5, [](const Data &d) //用for_each 遍历数组
{
cout << d.Num << " " << d.Sum << endl;
});
return 0;
}
在类内实现重载运算符然后直接用sort不传参3的
总结
这道题比较简单, 思路的话应该就是比较判断然后排个序
这段代码的话我用了较多语法方面的东西, 像lambda表达式, emplace_back防止调用拷贝构造,直接构造。
开始语言律师模式 基本跟题目无关,跟C++的语法斗智斗勇
这里的话,我原本是想在Data类中,定义operator> ,重载 > 运算符,然后直接用没带参3的sort直接排
代码如下
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n;
class Data
{
public:
int C;
int M;
int E;
int Sum;
int Num;
Data(int C, int M, int E, int Num)
:C(C),M(M),E(E),Num(Num) {this->Sum = C+M+E;}
bool operator>(const Data &A) // 重载了运算符号 > ,因为想当然的sort中用这个规则比较
{
if(this->Sum != A.Sum) return this->Sum > A.Sum;
if(this->C != A.C) return this->C > A.C;
return this-> Num < A.Num;
}
};
vector<Data> A;
int main()
{
cin >> n;
for(int i = 0; i < n; ++i)
{
int a,b,c;
cin >> a >> b >> c;
A.emplace_back(a,b,c,i+1);
}
sort(A.begin(),A.end());
for_each(A.begin(), A.begin() + 5, [](const Data &d)
{
cout << d.Num << " " << d.Sum << endl;
});
return 0;
}
编译失败
结果 : 编译不过
原因 :因为不带参的sort函数,由于其默认是升序排序,故其内部源码用的是 < 进行比较
从上图报错的信息也可以得知其由于其内部调用 *__it < __val, 然而我们并没有重载 < 运算符,故找不到报错.
解决方法 : 将operator> 修改为 operator < 即可通过编译
那如果继续重载> ,因为我们不是有 greater<> 模板 –> 包含头文件[HTML_REMOVED]
那我们修改代码 重新编译一下
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
int n;
class Data
{
public:
int C;
int M;
int E;
int Sum;
int Num;
Data(int C, int M, int E, int Num)
:C(C),M(M),E(E),Num(Num) {this->Sum = C+M+E;}
bool operator>(const Data &A)
{
if(this->Sum != A.Sum) return this->Sum > A.Sum;
if(this->C != A.C) return this->C > A.C;
return this-> Num < A.Num;
}
};
vector<Data> A;
int main()
{
cin >> n;
for(int i = 0; i < n; ++i)
{
int a,b,c;
cin >> a >> b >> c;
A.emplace_back(a,b,c,i+1);
}
sort(A.begin(),A.end(),greater<Data>());
for_each(A.begin(), A.begin() + 5, [](const Data &d)
{
cout << d.Num << " " << d.Sum << endl;
});
return 0;
}
编译失败
结果 : 编译不过
原因 :因为不带参的sort函数,由于其默认是升序排序,故其内部源码用的是 < 进行比较
从上图报错的信息也可以得知其由于其内部调用 __x > __y, 然而我们不是了重载 < 运算符,为啥还 no mathch ?
这时因为greater源码的为:
template<class _Ty = void>
struct greater
{ // functor for operator>
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty first_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty second_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef bool result_type;
constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
{ // apply operator> to operands
return (_Left > _Right);
}
};
可以看到其仿函数形式的形参为 const T& 类型, 而我们的sort的参三传参是 Data, 故这里被推导为 const Data&
好家伙!问题来了,由于这已经是一个const对象了,而我们重载的 > 成员函数是一个非const成员函数,故const对象
无法调用
解决方法 :
(1)直接在Data类的重载函数中后面加入 const修饰符 , 即可通过编译
(2) 将sort的参3的传参修改为 greater<Data&>, 这里最后会被推导出 Data& 类型,const会被丢弃, 详情见模板类型推导,这里不多解释.