如何使用IntStream对int数组的特定索引号求和?

时间:2018-12-19 21:42:33

标签: java lambda java-stream

因此,我一直在研究带有lambda的Kotlin和Java。尽管我对函数式编程知之甚少,但我还是在尝试尽可能多地使用函数式编程。

我正在使用HackerRank的问题进行研究(而Koans也在研究Kotlin)。我目前正在同时使用Kotlin和Java 8解决问题。

我正在尝试解决MiniMax-Sum问题https://www.hackerrank.com/challenges/mini-max-sum/

基本上,描述是这样的:

  

给出五个正整数,找到可以通过对五个整数中的四个精确求和而得出的最小值和最大值。然后将相应的最小值和最大值打印为两个空格分隔的长整数的单行。

我正在尝试使用Java中的大多数流API。一个简单的问题是:如何将排序后的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();

输入new long[] {256741038, 623958417, 467905213, 714532089, 938071625}的结果是10(最小)和15(最大)


非常感谢所有花时间提供帮助的人!猜猜我没有看到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 :(得分:6)

尽管您可以通过排序解决此任务,如其他答案所示,但这不是必需的工作。 “将五分之四的值相加”表示“除一个以外的所有值”,因此您要做的就是从所有元素的总和中减去一个元素。减去最大元素得到的最小和为四,减去最小元素得到的最大和为四:

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

答案 1 :(得分:3)

您可能正在寻找类似Intstream.range(int startInclusive, int endExclusive)

  

endInc(包括)返回顺序的有序IntStream   到startInclusive(不包括)以递增的1步。

在这些之上,您可以直接执行endExclusive或将IntSummaryStatisticssum一起使用以进一步访问计数,平均值,最大值,最小值等。

Edit2 :如果您希望获得的金额为summaryStatistics(),请使用summaryStatistics().getSum()

Edit2 :如果您专门想访问数组数据的统计信息,则可以使用Arrays.stream​(int[] array, int startInclusive, int endExclusive),它会返回一个{ {1}}。

答案 2 :(得分:1)

如果您真的要使用流,请利用跳过和限制:

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

这假设您已经有一个现有的数组,并且只想在Java中复制您的Kotlin代码。


要生成索引,请查看IntStream.range

例如

IntStream.range(0, 4);

IntStream0返回到3,即4是互斥的,IntStream.rangeClosed(startInc, endInc)使一个人能够从startInc到{{ 1}}(含)。