简体   繁体   English

使用java8流api累积查找限制10的索引

[英]use java8 stream api to accumulation find index for limit 10

I am learning java8 stream api. 我正在学习java8流api。 igot face this problem. 忘记面对这个问题。 Here have 9 number "1,2,3,4,5,6,7,8,9". 这里有9个数字“ 1,2,3,4,5,6,7,8,9”。 I want find n for 1+2+3+....+n>=10 . 我想为1 + 2 + 3 + .... + n> = 10找到n。 How can I use java8 stream api to find n? 如何使用java8流api查找n?

i tried use for loop to find n, code like this: 我试图用for循环来找到n,像这样的代码:

int sum,n=0;
for(int i=0;i<arr.length;i++){
    sum+=arr[i]
    if(sum>=10){
        n=i;
        break;
    }
}
int n = IntStream.range(0, arr.length)
        .filter(i -> Arrays.stream(arr).limit(i + 1).sum() >= 10)
        .findFirst()
        .orElse(-1);
System.out.println(n); // return 3 (1 + 2 + 3 + 4 = 10)

Your code is contradicting your problem description. 您的代码与您的问题描述矛盾。 You say that you want n such that 1+2+3+....+n>=10 , but you are assigning i , the index of n in the array to n . 你说你要的n,以便1+2+3+....+n>=10 ,但是要分配i ,n的阵列中的索引 n Theses two correlate only if you have these ascending numbers in the array, but if you assume that fixed content, you wouldn't need the array at all. 仅当您在数组中具有这些升序数字时,这两个变量才相关,但是如果您假设固定内容,则根本不需要该数组。

Further, you are not incrementing sum at all; 此外,您根本不会增加sum it's zero all the time. 一直都是零。

If you assume a sequence of ascending integers only, you can get n without iterating: 如果仅假设一个升序整数序列,则无需迭代即可获得n

int threshold = 10;

long n = Math.round(Math.sqrt(threshold*2));//that's it
System.out.println("solution: n = "+n);

// the rest is only verification and reporting
long actualSum = LongStream.rangeClosed(1, n).sum();
assert actualSum >= threshold;
assert actualSum - n < threshold;

System.out.println(LongStream.rangeClosed(1, n)
    .mapToObj(String::valueOf).collect(Collectors.joining(" + ")));
System.out.println("\t = "+actualSum+" >= "+threshold);

If you want to get the solution for an arbitrary sequence stored in an array, a loop is the simplest and most efficient sequential solution: 如果要获取存储在数组中的任意序列的解决方案,则循环是最简单,最有效的顺序解决方案:

int i, sum;
for(i = 0, sum = 0; i < arr.length && sum < threshold; i++) sum += arr[i];

if(sum >= threshold) {
    System.out.println("solution: index = "+(i-1)+", n = "+arr[i-1]);
    System.out.println(Arrays.stream(arr, 0, i)
            .mapToObj(String::valueOf).collect(Collectors.joining(" + ")));
    System.out.println("\t = "+sum+" >= "+threshold);
} else {
    System.out.println("No solution with this array");
}

If you have a large array and want to utilize parallel processing, you may use 如果阵列很大,并且想利用并行处理,则可以使用

Arrays.parallelPrefix(arr, Integer::sum);
int i = Arrays.binarySearch(arr, threshold);
if(i < 0) i = -i-1;

if(i < arr.length){
    System.out.println("solution: index = "+i+", n = "+(arr[i]-(i==0? 0: arr[i-1])));
    System.out.println(arr[0]+" + "+IntStream.rangeClosed(1, i)
        .mapToObj(ix -> String.valueOf(arr[ix]-arr[ix-1]))
        .collect(Collectors.joining(" + ")));
    System.out.println("\t = "+arr[i]+" >= "+threshold);
} else {
    System.out.println("No solution with this array");
}

But this modifies the array. 但这会修改​​数组。 This modification is reversible, as the example demonstrates, we can print the original sequence, but such a modification may not always be feasible. 如示例所示,这种修改是可逆的,我们可以打印原始序列,但是这种修改可能并不总是可行的。 If we have to make a copy or transform the array back to its original state, we may already lose any advantage of parallel processing, so the loop stays the best option in these cases. 如果必须进行复制或将数组转换回其原始状态,则可能已经失去了并行处理的任何优势,因此在这些情况下,循环仍然是最佳选择。 You need a sufficiently large array anyway, to have a chance of getting a performance benefit from parallel processing. 无论如何,您都需要一个足够大的阵列,才能有机会从并行处理中获得性能优势。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM