C Algorithms – Simple and Clean Way to Compare Three Numbers

algorithmsc

I've got some code that has a sequence of ifs that work, but just feel messy. Basically, I want to choose the largest of three integers and set a status flag to say which was chosen. My current code looks like this:

a = countAs();
b = countBs();
c = countCs();

if (a > b && a > c)
    status = MOSTLY_A;
else if (b > a && b > c)
    status = MOSTLY_B;
else if (c > a && c > b)
    status = MOSTLY_C;
else
    status = DONT_KNOW;

This pattern occurs a few times, and with long variable names it gets a little difficult to visually confirm that each if is correct. I feel there might be a better and clearer way to do this; can anyone suggest anything?


There are some potential duplicates, but they don't quite align with this question.

In the suggested duplicate: Approaches to checking multiple conditions? all of the suggested solutions seem equally clumsy as the original code, so they do not provide a better solution.

And this post Elegant ways to handle if(if else) else deals only with nesting levels and asymmetry, which is not the problem here.

Best Answer

Factorize logic, return early

As suggested in comments, it would be sufficient to simply wrap your logic in a function and exit early with return's in order to simplify things a lot. Also, you could factorize a bit of functionnality by delegating tests to another function. More concretely:

bool mostly(max,u,v) {
   return max > u && max > v;
}

status_t strictly_max_3(a,b,c)
{
  if mostly(a,b,c) return MOSTLY_A;
  if mostly(b,a,c) return MOSTLY_B;
  if mostly(c,a,b) return MOSTLY_C;
  return DONT_KNOW;
}

This is shorter than my previous attempt:

status_t index_of_max_3(a,b,c)
{
  if (a > b) {
    if (a == c)
      return DONT_KNOW;
    if (a > c)
      return MOSTLY_A;
    else
      return MOSTLY_C;
  } else {
    if (a == b)
      return DONT_KNOW;
    if (b > c)
      return MOSTLY_B;
    else
      return MOSTLY_C;
  }
}

The above is a little more verbose, but is easy to read IMHO and does not recompute comparisons multiple times.

Visual confirmation

In your answer you say:

my issue was mostly visual confirmation that all comparisons used the same variables

... also, in your question, you say:

This pattern occurs a few times, and with long variable names it gets a little difficult to visually confirm that each if is correct.

I may not understand what you are trying to achieve: do you want to copy-paste the pattern everywhere you need it? With a function like the one above, you capture the pattern once, and you check once for all that all comparisons use a, b and c as required. Then, you don't need to worry anymore when you call the function. Of course, maybe in practice your problem is a little more complex than the one you described: if so, please add some details if possible.