Java 中我的比较器接口的 ArrayIndexOutOfBoundsException

ArrayIndexOutOfBoundsException for my Comparator Interface in Java

我正在学习 Comparator 接口来解决小数背包问题。 a 和 b 行中的两个数组表示 3 个值-权重对 - (60, 20), (100, 50), (120, 30)。比较器应该根据 v[i]/w[i] 的比率对 arr[] 进行排序。但是,以下代码给了我奇怪的错误:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3

我的比较器似乎试图访问 arr[] 的 index=3,但我无法限制它对索引的访问。有什么解决办法吗?

这是我的代码:

int[] v = {60, 100, 120};  // v: values. line a
int[] w = {20, 50, 30};   // w: weights. line b
int len = v.length;
Integer[] arr = new Integer[len];

for (int i=0; i<len; i++) 
  arr[i] = v[i] / w[i];

//sort arr[] based on the ratios of v[i]/w[i]
Arrays.sort(arr, new Comparator<Integer>() {
  @Override public int compare(Integer o1, Integer o2) {
      return Double.compare(v[o1]/w[o1], v[o2]/w[o2]);
  }
});

double[] v_sorted = new double[len];
double[] w_sorted = new double[len];
for (int i = 0; i < len; ++i) {
  v_sorted[i] = v[arr[i]];
  w_sorted[i] = w[arr[i]];
}

问题是您正在尝试对索引进行排序,如比较器代码中的 o1o2 所示,但您的 arr 包含预先计算的比率。

用数字 0len-1 填充数组,包括在内,将解决问题:

for (int i=0; i<len; i++) 
    arr[i] = i;

现在比较器会得到一对索引,并根据它们比较v[...]w[...]的比率。

在你的代码中你想要双打,但你正在创建 Integer array.Also 其他一些逻辑错误 exist.Have 请看下面:

import java.util.Arrays;

public class Example {

    public static void main(String[] args) {

        // Initialize arrays `values`,`weights`,arr
        int[] values = { 60, 100, 120 };
        int[] weights = { 20, 50, 30 };
        int valuesArrayLength = values.length;

        Double[] array = new Double[valuesArrayLength];

        // For loop
        for (int i = 0; i < valuesArrayLength; i++)
            array[i] = (double) (values[i] / weights[i]);

        //Pre Java8 way(@Deprecated)
        // Arrays.sort(arr, new Comparator<Double>() {
        //     @Override
        //      public int compare(Double o1, Double o2) {
        //        return Double.compare(o1,o2);
        //     }
        // });
        // Sort array using a Comparator (lambda expression)
        Arrays.sort(array, (o1, o2) -> Double.compare( o1,o2));
        //The above can be even reduced to (method reference)
        //Arrays.sort(array, Double::compare);

        // Finally
        int[] valuesSorted = Arrays.stream(values).sorted().toArray();
        int[] weightsSorted = Arrays.stream(weights).sorted().toArray();

        // Testing the arrays
        System.out.println("array sorted:" + Arrays.toString(array));
        System.out.println("valuesSorted:" + Arrays.toString(valuesSorted));
        System.out.println("weightsSorted:" + Arrays.toString(weightsSorted));
    }
}