我知道如何在数组(列表)中找到最高值和索引。但是,如果数组中有多个最高值,我不知道如何获取索引。我想创建一个方法/函数,可以做两件事:如果只有一个最高值,只用一个索引填充数组(列表),或者如果有多个最高值,则创建一个arraylist。例如,我给出了两个数组:
Array1={42,3,42,42,42,5,8};
我想在新数组(列表)中获取值42的所有索引。
Array2={42,3,35,67};
我想创建一个只有一个值为42的索引的数组(列表)。
答案 0 :(得分:0)
尝试使用多个索引
List<Integer> list = new ArrayList<>();
int array[] = {1,1,2,4,5,3,1,5};
int max = array[0];
list.add(0);
for(int i=1;i<array.length;i++){
if(max<array[i]){
max = array[i];
list.clear();
list.add(i);
}else if(max==array[i])
list.add(i);
}
System.out.println(list);
对于单个索引,使用额外的变量来存储它。
答案 1 :(得分:0)
使用Java 8功能并假设数组不为空:
int maxValue = Arrays.stream(array)
.max()
.getAsInt();
int[] maxIndexes = IntStream.range(0, array.length)
.filter(i -> array[i] == maxValue)
.toArray();
这是2次迭代,首先找到最大值,然后是数组元素等于最大值的索引。
如果您不熟悉上面的某些类/方法,请参阅以下文档: IntStream,toArray(),getAsInt()
答案 2 :(得分:0)
根据您的方案,拥有较小的数据集或较大的数据集,您可能希望按顺序或并行处理这些项目。
注意:以下代码包含JUnit
@Test
注释和AssertJ
断言。
解决方案:顺序,一次通过,小数据集
此解决方案解析数组并跟踪最大和当前最大索引。如果找到新的最大值,则清除索引并插入新的最大索引。
@Test
public void sequential_algorithm_return_max_with_indexes() {
int[] values = new int[]{42, 3, 42, 42, 42, 5, 8};
int maxValue = Integer.MIN_VALUE;
List<Integer> maxValueIndexes = new ArrayList<>();
for (int index = 0; index < values.length; index++) {
int value = values[index];
if (value == maxValue) {
maxValueIndexes.add(index);
} else {
if (value > maxValue) {
maxValue = value;
maxValueIndexes.clear();
maxValueIndexes.add(index);
}
}
}
assertThat(maxValue).isEqualTo(42);
assertThat(maxValueIndexes).containsExactly(0, 2, 3, 4);
}
解决方案:并行,大数据集
Streams非常灵活,允许并行处理。
Bellow数据表示为一对索引值而不是数组。这样做是为了将对数组转换为流并跟踪索引。
因为这应该并行工作,reduce
方法接受3个参数 - 初始值,累加器和组合器。这意味着多个桶并行运行。对于每个桶,都有一个初始值和一个用于按顺序处理项目的累加器。然后使用组合器参数组合桶的并行结果。
@Test
public void parallel_algorithm_return_max_with_indexes() {
Pair<Integer, Integer>[] values = new Pair[]{
new Pair<>(0, 42),
new Pair<>(1, 3),
new Pair<>(2, 42),
new Pair<>(3, 42),
new Pair<>(4, 42),
new Pair<>(5, 5),
new Pair<>(6, 8),
};
ValueIndexes<Integer> maxValueIndexes = Arrays.stream(values)
.parallel()
.reduce(
new ValueIndexes<>(Integer.MIN_VALUE),
(ValueIndexes<Integer> valueIndexes, Pair<Integer, Integer> value) -> {
if (valueIndexes.getValue() == value.getValue()) {
valueIndexes.addIndex(value.getKey());
} else {
if (value.getValue() > valueIndexes.getValue()) {
valueIndexes = new ValueIndexes<>(value.getValue());
valueIndexes.addIndex(value.getKey());
}
}
return valueIndexes;
},
(valueIndexes1, valueIndexes2) -> {
if (valueIndexes1.getValue() == valueIndexes2.getValue()) {
ValueIndexes<Integer> valueIndexes = new ValueIndexes<>(valueIndexes1.getValue());
valueIndexes.addIndexes(valueIndexes1.getIndexes());
valueIndexes.addIndexes(valueIndexes2.getIndexes());
return valueIndexes;
} else {
if (valueIndexes1.getValue() > valueIndexes2.getValue()) {
return valueIndexes1;
} else {
return valueIndexes2;
}
}
}
);
assertThat(maxValueIndexes.getValue()).isEqualTo(42);
assertThat(maxValueIndexes.getIndexes()).containsExactlyInAnyOrder(0, 2, 3, 4);
}
private class ValueIndexes<T> {
private T value;
private List<Integer> indexes = new ArrayList<>();
public ValueIndexes(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public Iterable<Integer> getIndexes() {
return indexes;
}
public void addIndexes(Iterable<Integer> indexes) {
indexes.forEach(this::addIndex);
}
public void addIndex(int index) {
indexes.add(index);
}
}