使用java8流api查找限制10的索引
我正在学习java8流api。我不能面对这个问题。 这里有9个数字1,2,3,4,5,6,7,8,9。 我想找到1+2+3+n>=10的n。 如何使用java8流api来查找n 我尝试使用for循环查找n,代码如下:使用java8流api查找限制10的索引,java,java-8,java-stream,Java,Java 8,Java Stream,我正在学习java8流api。我不能面对这个问题。 这里有9个数字1,2,3,4,5,6,7,8,9。 我想找到1+2+3+n>=10的n。 如何使用java8流api来查找n 我尝试使用for循环查找n,代码如下: int sum,n=0; for(int i=0;i<arr.length;i++){ sum+=arr[i] if(sum>=10){ n=i; break; } } 您的代码与问题描述相矛盾。你说你想要n使得
int sum,n=0;
for(int i=0;i<arr.length;i++){
sum+=arr[i]
if(sum>=10){
n=i;
break;
}
}
您的代码与问题描述相矛盾。你说你想要n使得1+2+3+..+n>=10,但是你把i,数组中n的索引赋值给n。只有当数组中有这些递增的数字时,这两个值才相关,但如果假设内容是固定的,则根本不需要数组 此外,您根本没有增加总和;一直是零 如果您仅假设一个升序整数序列,则可以在不迭代的情况下得到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);
如果要获得存储在数组中的任意序列的解决方案,循环是最简单和最有效的顺序解决方案:
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");
}
如果您有一个大型阵列,并且希望利用并行处理,那么可以使用
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");
}
但这会修改数组。这种修改是可逆的,正如示例所示,我们可以打印原始序列,但这种修改可能并不总是可行的。如果我们必须复制或将数组转换回其原始状态,我们可能已经失去了并行处理的任何优势,因此在这些情况下,循环仍然是最佳选择。无论如何,您需要一个足够大的数组,以便有机会从并行处理中获得性能优势。您的代码与您的问题描述相矛盾。你说你想要n使得1+2+3+..+n>=10,但是你把i,数组中n的索引赋值给n。只有当数组中有这些递增的数字时,这两个值才相关,但如果假设内容是固定的,则根本不需要数组 此外,您根本没有增加总和;一直是零 如果您仅假设一个升序整数序列,则可以在不迭代的情况下得到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);
如果要获得存储在数组中的任意序列的解决方案,循环是最简单和最有效的顺序解决方案:
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");
}
如果您有一个大型阵列,并且希望利用并行处理,那么可以使用
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");
}
但这会修改数组。这种修改是可逆的,正如示例所示,我们可以打印原始序列,但这种修改可能并不总是可行的。如果我们必须复制或将数组转换回其原始状态,我们可能已经失去了并行处理的任何优势,因此在这些情况下,循环仍然是最佳选择。无论如何,您需要一个足够大的阵列,以便有机会从并行处理中获得性能优势。这看起来会产生正确的答案+1,但我想知道是否可以更有效地完成,即避免在每次执行筛选器时反复计算部分和。我认为您不会得到比使用流的现有代码更有效的代码。仅仅是所有的方法调用都会使它比你的代码慢。这可以更有效地完成——这是可能的,但会产生副作用,比如流外的变量对流的设计不好。当顺序不一致时,流对于处理单独的元素更有效。谢谢,我的领导让我使用java流api来代替for语句,这可能是一个很好的选择mistake@ViacheslavVedenin即使这样,它也只适合于顺序流-对于并行流,即使是一个AtomicInteger也无济于事这看起来会产生正确的答案+1,但我想知道是否可以更高效地完成这项工作,即避免在每次执行筛选器时反复计算部分和。我不认为您得到的代码会比使用流的现有代码更高效。仅仅是所有的方法调用都会使它比你的代码慢。这可以更有效地完成——这是可能的,但会产生副作用,比如流外的变量对流的设计不好。当顺序不一致时,流对于处理单独的元素更有效。谢谢,我的领导让我使用java流api来代替for语句,这可能是一个很好的选择mistake@ViacheslavVedenin即使这样,它也只适合于顺序流-对于并行流,即使是一个原子整数也帮不上忙。老实说,我想到了这个长n=Math.roundMath.sqrtthreshold*2;但它假设一个连续数组,不知道OP是否真的意味着that@Eugene这就是我之所以做出这种区分的原因。谢谢,我修改了我的代码。我认为java stream api做得太复杂,可读性和性能太差。老实说,我想到了这个长n=Math.roundMath.sqrtthreshold*2;但它假设一个连续数组,不知道OP是否真的意味着that@Eugene这就是为什么我做了这样的区分。谢谢,我修改了我的代码。我认为java stream api做的太复杂了,可读性和性能差。目前,java stream api不适合解决这个问题。目前,java stream api不适合 我们需要解决这个问题