Given is an array of three numeric values and I\'d like to know the middle value of the three.
The question is, what is the fastest way of finding the midd
If you are looking for the most efficient solution, I would imagine that it is something like this:
if (array[randomIndexA] > array[randomIndexB]) {
if (array[randomIndexB] > array[randomIndexC]) {
return "b is the middle value";
} else if (array[randomIndexA] > array[randomIndexC]) {
return "c is the middle value";
} else {
return "a is the middle value";
}
} else {
if (array[randomIndexA] > array[randomIndexC]) {
return "a is the middle value";
} else if (array[randomIndexB] > array[randomIndexC]) {
return "c is the middle value";
} else {
return "b is the middle value";
}
}
This approach requires at least two and at most three comparisons. It deliberately ignores the possibility of two values being equal (as did your question): if this is important, the approach can be extended to check this also.
100% branch-free version for integers:
int mid(const int a, const int b, const int c) {
const int d0 = b - a;
const int m = (d0 >> 31);
const int min_ab = a + (d0 & m);
const int max_ab = a + (d0 & ~m);
const int d1 = c - max_ab;
const int min_max_ab_c = max_ab + (d1 & (d1 >> 31));
const int d2 = min_ab - min_max_ab_c;
return min_ab - (d2 & (d2 >> 31));
}
Constructed using the branch-free min / max functions:
int min(const int a, const int b) { const int d = b - a; return a + (d & (d >> 31)); }
int max(const int a, const int b) { const int d = a - b; return a - (d & (d >> 31)); }
It may not look pretty but the machine code might prove more efficient on some architectures. Especially those without min / max instructions. But I have not made any benchmarks to confirm it.
A lot of these seem to be using pretty complex if statements. I've found a really simple workaround using the Math library.
Math.max(Math.min(array[start], array[mid]), Math.min(array[start], array[mid], array[end]))
Works out quite nicely.
It can be solved in one line by the ternary operator
int middle(int A, int B, int C) {
return (A>B&&A>C)?B>C?B:C:(B>C&&B>A)?A>C?A:C:B;
}
If you must find one out of X values satisfying some criteria you have to at least compare that value to each of the X-1 others. For three values this means at least two comparisons. Since this is "find the value that is not the smallest and not the largest" you can get away with only two comparisons.
You should then concentrate on writing the code so you can very clearly see what goes on and keep it simple. Here this means nested if's. This will allow the JVM to optimize this comparison as much as possible at runtime.
See the solution provided by Tim (Fastest way of finding the middle value of a triple?) to see an example of this. The many code line does not necessarily turn out to be larger code than nested questionmark-colon's.
if(array[aIndex] > array[bIndex]) {
if(array[bIndex] > array[cIndex]) return bIndex;
if(array[aIndex] > array[cIndex]) return cIndex;
return aIndex;
} else {
if(array[bIndex] < array[cIndex]) return bIndex;
if(array[aIndex] < array[cIndex]) return cIndex;
return aIndex;
}