Given a sorted array, return the 'closest' element to the input 'x'.
I do understand the merits of unit testing in separate files, but I deliberately added it to the main method for personal convenience, so don't consider that in your feedback.
I'm looking for request code review, optimizations and best practices.
public final class ClosestToK {
private ClosestToK() { }
/**
* Given a sorted array returns the 'closest' element to the input 'x'.
* 'closest' is defined as Math.min(Math.abs(x), Math.abs(y))
*
* Expects a sorted array, and if array is not sorted then results are unpredictable.
*
* If two values are equi-distant then the greater value is returned.
*
* @param a The sorted array a
* @return The nearest element
*/
public static int getClosestK(int[] a, int x) {
int low = 0;
int high = a.length - 1;
while (low <= high) {
int mid = (low + high) / 2;
// test lower case
if (mid == 0) {
if (a.length == 1) {
return a[0];
}
return Math.min(Math.abs(a[0] - x), Math.abs(a[1] - x)) + x;
}
// test upper case
if (mid == a.length - 1) {
return a[a.length - 1];
}
// test equality
if (a[mid] == x || a[mid + 1] == x) {
return x;
}
// test perfect range.
if (a[mid] < x && a[mid + 1] > x) {
return Math.min(Math.abs(a[mid] - x), Math.abs(a[mid + 1] - x)) + x;
}
// keep searching.
if (a[mid] < x) {
low = mid + 1;
} else {
high = mid;
}
}
throw new IllegalArgumentException("The array cannot be empty");
}
public static void main(String[] args) {
// normal case.
int[] a1 = {10, 20, 30, 40};
assertEquals(30, getClosestK(a1, 28));
// equidistant
int[] a2 = {10, 20, 30, 40};
assertEquals(30, getClosestK(a2, 25));
// edge case lower boundary
int[] a3 = {10, 20, 30, 40};
assertEquals(10, getClosestK(a3, 5));
int[] a4 = {10, 20, 30, 40};
assertEquals(10, getClosestK(a4, 10));
// edge case higher boundary
int[] a5 = {10, 20, 30, 40};
assertEquals(40, getClosestK(a5, 45));
int[] a6 = {10, 20, 30, 40};
assertEquals(40, getClosestK(a6, 40));
// case equal to
int[] a7 = {10, 20, 30, 40};
assertEquals(30, getClosestK(a7, 30));
}
}
Math.Min(Math.Abs(x-el[i])
wherei
is all elements of the array? \$\endgroup\$ – Vogel612♦ Apr 16 '14 at 7:20