在ordererd列表中查找最接近的值

Man*_*lva 24 java

我想知道如何编写一个简单的java方法,在排序的整数列表中找到一个给定值的closet Integer.

这是我的第一次尝试:

public class Closest {

    private static List<Integer> integers = new ArrayList<Integer>();

    static {
        for (int i = 0; i <= 10; i++) {
            integers.add(Integer.valueOf(i * 10));
        }
    }

    public static void main(String[] args) {

        Integer closest = null;
        Integer arg = Integer.valueOf(args[0]);

        int index = Collections.binarySearch(
                integers, arg);

        if (index < 0) /*arg doesn't exist in integers*/ {
            index = -index - 1;
            if (index == integers.size()) {
                closest = integers.get(index - 1);
            } else if (index == 0) {
                closest = integers.get(0);
            } else {
                int previousDate = integers.get(index - 1);
                int nextDate =  integers.get(index);
                if (arg - previousDate < nextDate - arg) {
                    closest = previousDate;
                } else {
                    closest = nextDate;
                }
            }
        } else /*arg exists in integers*/ {
            closest = integers.get(index);
        }
        System.out.println("The closest Integer to " + arg + " in " + integers
                + " is " + closest);
    }
}
Run Code Online (Sandbox Code Playgroud)

您对此解决方案有何看法?我相信有一个更清洁的方式来完成这项工作......

也许这样的方法存在于Java库的某个地方而我错过了?

马努

dfa*_*dfa 33

尝试这个小方法:

public int closest(int of, List<Integer> in) {
    int min = Integer.MAX_VALUE;
    int closest = of;

    for (int v : in) {
        final int diff = Math.abs(v - of);

        if (diff < min) {
            min = diff;
            closest = v;
        }
    }

    return closest;
}
Run Code Online (Sandbox Code Playgroud)

一些测试用例:

private final static List<Integer> list = Arrays.asList(10, 20, 30, 40, 50);

@Test
public void closestOf21() {
    assertThat(closest(21, list), is(20));
}

@Test
public void closestOf19() {
    assertThat(closest(19, list), is(20));
}

@Test
public void closestOf20() {
    assertThat(closest(20, list), is(20));
}
Run Code Online (Sandbox Code Playgroud)

  • 这种方法表现不佳.如果我的数组的值高达10 000 000,我想要的是5 000 000,它将进行10 000 000次迭代才能找到它.最佳算法是二分法(在这种情况下,它将需要1或2次迭代. (3认同)

Nic*_*hel 14

Kotlin 很有帮助

fun List<Int>.closestValue(value: Int) = minBy { abs(value - it) }

val values = listOf(1, 8, 4, -6)

println(values.closestValue(-7)) // -6
println(values.closestValue(2)) // 1
println(values.closestValue(7)) // 8

Run Code Online (Sandbox Code Playgroud)

列表不需要排序 BTW

编辑:自 kotlin 1.4 起,minBy已弃用。更喜欢minByOrNull

@Deprecated("Use minByOrNull instead.", ReplaceWith("this.minByOrNull(selector)"))
@DeprecatedSinceKotlin(warningSince = "1.4")
Run Code Online (Sandbox Code Playgroud)