Как я могу использовать IntStream для суммирования определенных индексированных чисел массива int? - PullRequest
0 голосов
/ 20 декабря 2018

Я изучал Kotlin и Java с лямбдами.Я стараюсь максимально использовать функциональное программирование, которое только могу, хотя я не очень разбираюсь в функциональном программировании.

Я использую проблемы HackerRank для изучения (и Коанов для изучения Kotlin),В настоящее время я решаю проблемы, используя как Kotlin, так и Java 8.

Я пытаюсь решить проблему MiniMax-Sum .По сути, описание выглядит примерно так:

Учитывая пять положительных целых чисел, найдите минимальные и максимальные значения, которые можно вычислить, суммируя ровно четыре из пяти целых чисел.Затем выведите соответствующие минимальное и максимальное значения в виде одной строки из двух разделенных пробелом длинных целых чисел.

Я пытаюсь использовать большинство API потоков, которые я могу использовать в Java.Простой вопрос: как я могу уменьшить, после сортировки, массив int до его четырех первых элементов (и, наконец, в другом сценарии) и суммировать его значения?Я пытался использовать IntStream, но кажется, что это очень сложно без использования List.Мне было интересно, можно ли напрямую использовать массив int[] с IntStream для сортировки и сокращения элементов и их суммирования.

Используя Kotlin, я решил так:

val minSum: Long = arr.sortedArray().copyOfRange(0, 4).sum().toLong()
val maxSum: Long = arr.sortedArray().copyOfRange(1, 5).sum().toLong()
println("$minSum $maxSum")

Я пытаюсь использовать метод range вместе с sorted и sum.Оно работает.Проблема в том, что сумма всегда возвращает int, а иногда сумма равна long.Вот мой код:

long min = IntStream.range(0, arr.length)
        .sorted()
        .sum();

long max = IntStream.range(1, arr.length + 1)
        .sorted()
        .sum();

Результат 10 (мин) и 15 (макс) для ввода new long[] {256741038, 623958417, 467905213, 714532089, 938071625}


Большое спасибо всем, кто нашел время, чтобы помочь!Думаю, я не видел метод LongStream.of: D я решил двумя разными способами (указанными @Aomine, @nullpointer и @Holger):

// using Arrays and Stream
Arrays.sort(arr);
long min = Arrays.stream(arr, 0, 4).sum();
long max = Arrays.stream(arr, 1, 5).sum();

System.out.println(min + " " + max);

// and using LongSummaryStatistics (thanks @Holger)
LongSummaryStatistics ls = LongStream.of(arr).summaryStatistics();
System.out.println((ls.getSum() - ls.getMax()) + " " + (ls.getSum() - ls.getMin()));

Спасибо большое, ребята!

Ответы [ 3 ]

0 голосов
/ 20 декабря 2018

Возможно, вы просто ищете что-то вроде Intstream.range(int startInclusive, int endExclusive)

Возвращает последовательно упорядоченный IntStream от startInclusive (включительно) до endExclusive (эксклюзив)шаг приращения 1.

В этом случае вы можете выполнить либо sum напрямую, либо использовать IntSummaryStatistics с summaryStatistics() для дальнейшего доступа к счетчику, среднему, максимальному,мин и т. д.

Edit2 : Если вы хотите получить сумму как long, используйте summaryStatistics().getSum()

Edit2 : Если вы специально хотите получить доступ к статистике данных массива, вы можете использовать Arrays.stream​(int[] array, int startInclusive, int endExclusive), который вернется назадInstream.

0 голосов
/ 20 декабря 2018

Хотя вы можете решить эту задачу путем сортировки, как показано в других ответах, это ненужная работа.«Суммирование четырех из пяти» значений означает «суммирование всех, кроме одного», поэтому все, что вам нужно сделать, это вычесть один элемент из суммы всех элементов.Вычтите максимальный элемент, чтобы получить минимальную сумму четырех, вычтите минимальный элемент, чтобы получить максимальную сумму четырех:

IntSummaryStatistics s = IntStream.of(1, 3, 5, 7, 9).summaryStatistics();
System.out.printf("%d %d%n", s.getSum()-s.getMax(), s.getSum()-s.getMin());
16 24

Или, если источником является массив:

IntSummaryStatistics s = Arrays.stream(array).summaryStatistics();
System.out.printf("%d %d%n", s.getSum()-s.getMax(), s.getSum()-s.getMin());
0 голосов
/ 20 декабря 2018

если вы действительно хотите использовать поток, используйте пропуск и ограничение:

Arrays.stream(myArray).sorted().limit(4).sum();
Arrays.stream(myArray).sorted().skip(1).limit(4).sum();

это предполагает, что у вас уже есть существующий массив и вы просто хотите скопировать свой код Kotlin в java.


Что касается генерации индексов, изучите IntStream.range.

например,

IntStream.range(0, 4);

возвращает IntStream из 0 до 3 т.е. 4 является эксклюзивным, IntStream.rangeClosed(startInc, endInc) позволяет генерировать индексы от startInc до endInc включительно.

...