题目4-多关键字排序
有一组商品记录,每件商品的属性包含名称、价格、好评等级等。现在需要对这组商品实现多关键字排序,可以实现如下功能:比如,总体来说按好评等级排序(从高到低),但是好评等级相同的情况下,再按价格从低到高排序。或者,总体来说价格排序,价格相同的情况下按好评等级排序。
解决方案
首先看到题目,关键字排序,我就联想到近期学的自定义比较函数,本次就按等级排序。
- 如果等级较高,排在前面(这意味着等级低,即使价格再低,也会排在等级高的后面)
- 等级相同的情况下,价格较低排在前面
原理
自定义比较函数(有点绕),可以理解为制定一个规则。
struct student
{
int num;//学号
int age;//年龄
};
bool cmp(student a, student b)
{
if (a.age > b.age)
return 1;
else if (a.age < b.age)
return 0;
else if (a.num > b.num)
return 1;
else return 0;
}
我们先假定知道学生的年龄,学号,那么我们按照年龄大的排在前面,年龄低的排在后面。如果年龄一样,则按学号大的在前,小的在后。
我们先这样理解,return 1,则a比b的年龄指标大,则a排在b的前面,反之,return 0,则b比a的年龄大,则b排在a的前面。一个数组或者容器
的元素都按照这个规则排序,那么这个数组或者容器就排好序了。
代码
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
struct goods
{
char grade;
string name;
int price;
}a[50];
bool cmp(goods a, goods b)
{
if (a.grade < b.grade)//如果a的等级比b高,但是这边是因为‘A'<'B',所以采用小于号
{
return 1;
}
else if (a.grade == b.grade)
{
if (a.price <= b.price)//如果等级相等a比b便宜
return 1;
else return 0;//如果等级相等a比b贵
}
else return 0;//如果a等级比b低;
}
int main()
{
a[0].grade = 'A';
a[0].name = "AJ";
a[0].price = 100;
a[1].grade = 'B';
a[1].name = "NIKE";
a[1].price = 80;
a[2].grade = 'A';
a[2].name = "Li ning";
a[2].price = 120;
a[3].grade = 'A';
a[3].name = "ANTA";
a[3].price = 80;
a[4].grade = 'D';
a[4].name = "pdd";
a[4].price = 20;
sort(a, a + 5, cmp);
for (int i = 0; i < 5; i++)
cout << a[i].name << endl;
}
AJ | NIKE | ANTA | Li Ning | pdd | |
grade | A | B | A | A | D |
price | 100 | 80 | 80 | 120 | 20 |
输出结果
按照先后,输出名字,
- ANTA 等级A 价格80
- AJ 等级A 价格100
- Li Ning 等级A 价格120.
- NIKE 等级B 价格80
- pdd 等级D 价格20
可以看到,等级一样,价格低的排在前面。
等级低,价格再便宜也只能排在后面
复杂度O(n)
输入输出都是在O(n)时间内完成,这里为了简化,就直接写好了。
排序可以在常数时间完成。
拓展:重载运算符
struct goods
{
char grade;
string name;
int price;
bool operator < (const goods& b)const {
if (grade < b.grade)//如果a的等级比b高,但是这边是因为‘A'<'B',所以采用小于号
{
return 1;
}
else if (grade == b.grade)
{
if (price <= b.price)//如果等级相等a比b便宜
return 1;
else return 0;//如果等级相等a比b贵
}
else return 0;//如果a等级比b低;
}
}a[50];
简单来说:就是这里的if (grade < b.grade) 相当于 if (this.grade < b.grade) 下面类似
这样的功能就和上面的cmp相似。
那么用sort排序,就可以不用写第三个参数了。