我想对date
s的向量进行排序,我为它编写了比较函数:
#include <iostream>
struct date {
int day;
int month;
int year;
};
int compare_dates(date a, date b) {
if (a.year < b.year) {
return -1;
} else if (a.year == b.year) {
if (a.month < b.month) {
return -1;
} else if (a.month == b.month) {
if (a.day < b.day) {
return -1;
} else if (a.day > b.day) {
return 1;
}
} else {
return 1;
}
} else {
return 1;
}
return 0;
}
int main() {
date a = {};
date a.day = 19;
date a.month = 11;
date a.year = 2016;
date b = {};
date b.day = 20;
date b.month = 11;
date b.year = 2016;
compare_dates(a, b) // -1
compare_dates(b, a) // 1
compare_dates(b, b) // 0
return 0;
}
效果很好,但compare_dates
功能看起来很糟糕。有什么想法我怎么能改进它?
答案 0 :(得分:3)
这足以将日期容器按升序排序:
bool compareDates(date const& lhs, date const& rhs) const {
if(lhs.year == rhs.year) {
if(lhs.month == rhs.month) {
return lhs.day < rhs.day;
}
return lhs.month < rhs.month;
}
return lhs.year < rhs.year;
}
// sort(dates, dates + n, compareDates);
我故意没有单独处理-1
,因为我们不需要像std::sort()
,priority_queue
或std::set
那样覆盖STL容器的比较器提供整数返回码并使代码相对复杂。布尔就够了。
答案 1 :(得分:3)
我不是C ++专家,其他人指出std::sort()
不需要三方比较,只需要<
。但要按照书面清理代码:
您的compare_dates()
继续对>/</==
进行三方比较,并希望获得+1/-1/0
返回值。因此,声明一个三向cmp()
辅助函数,就像我们在Python中一样。现在您的代码缩减为:
int cmp(int x, int y) {
return (x>y) ? 1 : ((x<y) ? -1 : 0);
}
int compare_dates(date a, date b) {
if (cmp(a.year, b.year) != 0)
return cmp(a.year, b.year);
if (cmp(a.month, b.month) != 0)
return cmp(a.month, b.month);
return cmp(a.day, b.day);
}
如果高阶比较给出&#39; ==&#39;,您只能进行低阶比较。因此,您可以避免使用所有其他条款,大括号和缩进,从而使您的缩进级别保持不变并且很容易在眼睛上。它还调出了计算的对称性。
答案 2 :(得分:0)
使用一天仅使用4位而一个月仅使用5的事实呢?
#include <iostream>
struct date
{
int day;
int month;
int year;
};
int compare_dates (date a, date b)
{
long da { (a.year << 9) + (a.month << 4) + a.day };
long db { (b.year << 9) + (b.month << 4) + b.day };
return da < db ? -1 : (da > db);
}
int main()
{
date a = { 19, 11, 2016 };
date b = { 20, 11, 2016 };
std::cout << compare_dates(a, b) << std::endl; // print -1
std::cout << compare_dates(b, a) << std::endl; // print 1
std::cout << compare_dates(b, b) << std::endl; // print 0
return 0;
}
---编辑---
正如Christian Hackl所指出的,这段代码有点模糊。
如果您翻译date
结构中的位域部分,将其转换为union
,我希望这可以更加清晰。
因此,您可以初始化单独的year
,month
和day
组件,并使用full
组件进行比较。
以下内容
#include <iostream>
union date
{
struct
{
unsigned long day : 5U;
unsigned long month : 4U;
unsigned long year : 23U;
} s ;
unsigned long full;
};
int compare_dates (date const & a, date const & b)
{ return a.full < b.full ? -1 : (a.full > b.full); }
int main()
{
date a = { { 19, 11, 2016 } };
date b = { { 20, 11, 2016 } };
std::cout << compare_dates(a, b) << std::endl; // print -1
std::cout << compare_dates(b, a) << std::endl; // print 1
std::cout << compare_dates(b, b) << std::endl; // print 0
return 0;
}