Kann ich binaryContains
so ändern, dass das am dichtesten an x liegende Element zurückgegeben wird?
import java.util.Arrays;
import java.util.NoSuchElementException;
import java.util.Random;
public class BinarySearchWithAFuzzinessTest {
private static int testAndGetIndex(double[] list, double x, double delta, int i) {
if (Math.abs(x - list[i]) <= delta) {
while (i - 1 >= 0 && Math.abs(x - list[i - 1]) <= delta) {
i--;
}
return i;
}
return -1;
}
/**
* Returns the first occurrence, that fulfills the constraints.
*/
public static int binaryContains(double[] list, double x, double delta) {
if (list == null || list.length == 0) {
throw new NoSuchElementException("provide at least one element");
}
int i = 0;
int j = list.length / 2;
int k = list.length - 1;
while (true) {
System.out.println(i + " " + j + " " + k);
if (x + delta < list[i]) {
return -1;
}
int temp;
if ((temp = testAndGetIndex(list, x, delta, i)) != -1) {
return temp;
}
if ((temp = testAndGetIndex(list, x, delta, j)) != -1) {
return temp;
}
if ((temp = testAndGetIndex(list, x, delta, k)) != -1) {
return temp;
}
if (x < list[j]) {
k = j;
j = (i + j) / 2;
if (j == k) {
return -1;
}
} else if (x < list[k]) {
i = j;
j = (j + k) / 2;
if (i == j) {
return -1;
}
} else {
return -1;
}
}
}
/**
* Returns the first occurrence, that fulfills the constraints. This is for testing.
*/
public static int linearContains(double[] list, double x, double delta) {
for (int i = 0; i < list.length; i++) {
if (Math.abs(x - list[i]) <= delta) {
return i;
}
}
return -1;
}
public static void main(String[] args) {
Random r = new Random(1234);
for (int i = 0; i < 100000; i++) {
double[] a = new double[1 + r.nextInt(20)];
double x = r.nextInt(20) - 10;
double delta = r.nextDouble();
for (int j = 0; j < a.length; j++) {
if (r.nextBoolean()) {
a[j] = x + r.nextDouble() * 5 * delta;
} else {
a[j] = x - r.nextDouble() * 5 * delta;
}
}
Arrays.sort(a);
int c1 = binaryContains(a, x, delta);
int c2 = linearContains(a, x, delta);
if (c1 != c2) {
System.out.println("OOPS " + x + " " + delta);
System.out.println(Arrays.toString(a) + " " + c1 + " " + c2);
break;
}
}
}
}