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]];
}
问题是您正在尝试对索引进行排序,如比较器代码中的 o1
和 o2
所示,但您的 arr
包含预先计算的比率。
用数字 0
到 len-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));
}
}
我正在学习 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]];
}
问题是您正在尝试对索引进行排序,如比较器代码中的 o1
和 o2
所示,但您的 arr
包含预先计算的比率。
用数字 0
到 len-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));
}
}