Суммировать базовые элементы случайно вложенного массива в Java?

Учитывая многомерный массив целых чисел, как я могу найти сумму всех базовых элементов? В каждом массиве может быть разное количество массивов, поэтому мой алгоритм должен быть гибким, чтобы учитывать все возможные входные данные. Рекурсивный метод кажется наиболее элегантным решением. Пример:

Дано:

array = {
   {{1,2,3},
   {4,5},
   {6,7,8}},
   {{9},{10}}
}

Вернуть: 55

Обратите внимание, что длина каждого подмассива непостоянна и варьируется, как и глубина массива. Это означает, что традиционные циклы не смогут проверить длину массива, а рекурсивные методы не смогут определить количество измерений цикла в качестве начального параметра. Возможно, рекурсивный цикл должен был бы преобразовать Object в виде массива?


Редактировать:

Метод также должен иметь возможность суммировать массив ЛЮБОГО количества измерений. Например, входной массив может иметь три измерения или даже 7.

предоставить вывод того, что вы ожидаете от приведенного выше ввода

fuzious 29.06.2019 21:52
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
1
476
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Используя потоки Java, вы можете использовать только это (при условии, что ваш массив имеет 2 измерения):

int[][] array = {{1, 2, 3}, {4, 5}, {6, 7, 8}, {9, 10}};
int sum = Arrays.stream(array)
        .flatMapToInt(Arrays::stream)
        .sum();

Если ваш массив имеет 3 измерения, вы можете расширить его до следующего:

int[][][] array = {{{1, 2, 3}, {4, 5}, {6, 7, 8}}, {{9}, {10}}};
int sum = Arrays.stream(array)
        .flatMap(Arrays::stream)
        .flatMapToInt(Arrays::stream)
        .sum();

Для обработки массивов с неизвестной глубиной вы можете использовать этот метод для их выравнивания:

private static Stream<Object> flatMapDynamicArray(Object[] array) {
    return Arrays.stream(array)
            .flatMap(o -> o.getClass().isArray() ? 
                    flatMapDynamicArray((Object[]) o) : 
                    Stream.of(o));
}

Вы также можете использовать o instanceof Object[] вместо o.getClass().isArray(), но для моих тестов у второго было лучше.

Используйте этот метод следующим образом:

Integer[][][] array = {{{1, 2, 3}, {4, 5}, {6, 7, 8}}, {{9}, {10}}};
int sum = flatMapDynamicArray(array)
        .mapToInt(i -> (int) i)
        .sum();

Результатом во всех случаях будет 55 для массива, которым вы поделились.

Что делать, если вы не знаете, сколько измерений будет иметь родительский массив?

Frank Fanelli 29.06.2019 22:33

Итак, у вас есть Object в качестве входных данных?

Samuel Philipp 29.06.2019 22:46

Да, Object будет вводом, если это необходимо.

Frank Fanelli 29.06.2019 22:50

@FrankFanelli Я отредактировал свой вопрос. Надеюсь, это поможет справиться с массивами с неизвестной глубиной.

Samuel Philipp 29.06.2019 23:08

Мы можем использовать o.getClass().isArray() вместо o instanceof Object[].

Omid.N 30.06.2019 20:45

@OmidNejadabbasi Да, спасибо, что заметили. Я проверил это и обновил свой ответ в соответствии с этим.

Samuel Philipp 30.06.2019 23:27

Другая возможность, не использующая потоки или лямбда-выражения, — написать простой рекурсивный метод. Как и другие подобные конфликты, конфликты типов проявляются только во время выполнения.

Для следующей структуры вложенного массива:

      Integer[][][][] array = { { { { 1, 2, 3
            }, { 4, 5, 6
            }, { 7, 8, 9
            }
            }, { { 10, 11, 12,
            }, { 13, 14, 15
            }, { 16, 17, 19
            }
            }
            }, { { { 20, 21, 22
            }, { 23, 24, 25
            }
            }
            }
      };

   System.out.println(sum(array));

   public static int sum(Object[] a) {
      int sum = 0;
      for (Object o : a) {
         if (o instanceof Object[]) {
            sum += sum((Object[]) o);
         }
         if (o instanceof Integer) {
            sum += (Integer) o;
         }
      }
      return sum;
   }

Отпечатки

307

Другие вопросы по теме