Dmytro Rudnitskikh Dmytro Rudnitskikh - 13 days ago 4
C++ Question

How can I optimize compare function for custom date structure?

I want to sort a vector of

date
s and I wrote compare function for it:

#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;
}


It is working well, but
compare_dates
function looks awful. Is there any idea how can I improve it?

Answer

Your compare_dates() keeps doing three-way comparisons for >/</==, and wants a +1/-1/0 return value. So declare a three-way cmp() helper function which does that, like we do in Python. Now your code reduces to:

int cmp(int x, int y) {
    return (x>y) ? ( (x<y) ? -1 : 0 ) : 1; 
}

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);
} 

You only fall through into doing the lower-order comparisons if the higher-order comparison was '=='. So that allows you to avoid all the else-clauses, braces and indenting, which keeps your indent level constant and is easy on the eyes. It also calls out the symmetry of the computations.

Comments