在数组中查找最高值的索引。可以是1- *值

时间:2017-05-10 18:43:53

标签: java arrays arraylist max

我知道如何在数组(列表)中找到最高值和索引。但是,如果数组中有多个最高值,我不知道如何获取索引。我想创建一个方法/函数,可以做两件事:如果只有一个最高值,只用一个索引填充数组(列表),或者如果有多个最高值,则创建一个arraylist。例如,我给出了两个数组:

Array1={42,3,42,42,42,5,8};

我想在新数组(列表)中获取值42的所有索引。

Array2={42,3,35,67};

我想创建一个只有一个值为42的索引的数组(列表)。

3 个答案:

答案 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次迭代,首先找到最大值,然后是数组元素等于最大值的索引。

如果您不熟悉上面的某些类/方法,请参阅以下文档: IntStreamtoArray()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);
    }
}