【问题标题】:Find indexes of highest values in array. Can be 1-* values查找数组中最高值的索引。可以是 1-* 值
【发布时间】:2017-05-10 18:43:52
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 这个数组(列表)是什么?你的意思是数组int[] 还是List<Integer?

标签: java arrays arraylist max


【解决方案1】:

对多个索引试试这个

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);

对于单个索引,使用一个额外的变量来存储它。

【讨论】:

  • 这是一个效率较低的解决方案。双通通常会更好
  • @user2717954 同意,但这是最坏的情况。在一般情况下,它通常与循环两次相同,甚至更快。
【解决方案2】:

使用 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()

【讨论】:

    【解决方案3】:

    根据您的场景,拥有小数据集或大数据集,您可能希望按顺序或并行处理项目。

    注意:以下代码包含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);
    }
    

    解决方案:并行、大数据集

    流很灵活,允许并行处理。

    下面的数据表示为一对索引值而不是数组。这样做是为了将对数组转换为流并跟踪索引。

    因为这应该并行工作,reduce 方法接受 3 个参数 - 初始值、累加器和组合器。这意味着多个存储桶并行运行。对于每个桶,都有一个初始值和一个累加器,用于按顺序处理项目。然后使用 combiner 参数组合桶的并行结果。

    @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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-11-25
      • 2013-03-22
      • 1970-01-01
      • 2017-08-13
      • 1970-01-01
      • 1970-01-01
      • 2013-05-06
      • 2017-11-05
      相关资源
      最近更新 更多