Java8中除自身以外的数组元素的乘积,不带除法
在java-8中,如何不用除法解决以下问题Java8中除自身以外的数组元素的乘积,不带除法,java,java-8,Java,Java 8,在java-8中,如何不用除法解决以下问题 int [] arrays = {2,3,4,5}; int[] ints = Arrays.stream(arrays).map(s -> Arrays.stream(arrays).reduce(1, (x, y) -> x * y) / s) .toArray(); Arrays.stream(ints).forEach(
int [] arrays = {2,3,4,5};
int[] ints = Arrays.stream(arrays).map(s ->
Arrays.stream(arrays).reduce(1, (x, y) -> x * y) / s)
.toArray();
Arrays.stream(ints).forEach(System.out::println);
问题是:将数组中除self之外的所有元素生成一个乘积
例如:如果数组中有2,3,4
作为元素,那么最终的数组将如下所示:12,8,6
谢谢@Eran的快速回答,但我不能用O(n)来解决这个问题吗?您可以使用
过滤器
过滤掉您希望从产品中排除的术语:
int[] ints = Arrays.stream(arrays)
.map(s -> Arrays.stream(arrays).filter(x -> x != s).reduce(1, (x, y) -> x * y))
.toArray();
输出(针对您的输入阵列):
在O(n)中执行任务而不进行分割的解决方案是
int[] array = {2, 3, 4, 5};
int[] ints = new int[array.length];
ints[0] = 1;
for(int ix = 1, p = array[0]; ix < array.length; ix++) {
ints[ix] = p;
p *= array[ix];
}
for(int ix = array.length - 1, p = array[ix--]; ix >= 0; ix--) {
ints[ix] *= p;
p *= array[ix];
}
System.out.println(Arrays.toString(ints));
因此,使用两个循环的解决方案是这里的最佳选择。好吧,要在O(n)中解决它,您可以如下所示: 让我们制作
左数组
,右数组
,以及输出数组
。将左侧数组
的最左侧固定为1
,将右侧数组
的最右侧固定为1
现在要填充left_数组
您需要将原始数组从i=1
遍历到i=Array.length-1
//注意:我们已经修复了left_数组[0]=1的值
要填充right_数组
,您需要将原始数组从i=N-2
遍历到i=0
//注意:我们已经修复了right_数组[N-1]=1的值
现在要获得输出的数组[]
我们需要制作左数组[i]*右数组[i]的乘积代码>
int [] arrays = {2,3,4,5};
int N = arrays.length;
int [] left_Array = new int[N];
int [] right_Array = new int [N];
int [] output_Array = new int [N];
left_Array[0]=1;
right_Array[N-1]=1;
IntStream.range(1,N).forEach(s->left_Array[s]=arrays[s-1]*left_Array[s-1]);
for (int j = N-2;j>=0;j--){
right_Array[j]= arrays[j+1]*right_Array[j+1];
}
IntStream.range(0,N).forEach(k->output_Array[k]= left_Array[k]*right_Array[k]);
Arrays.stream(output_Array).forEach(System.out::println);
PS:如果有人可以为
right\u数组
循环,那就太好了
我同意另一种解决方案,即使用Stream
API并不能真正解决这个问题。此外,使用递归似乎也很容易:
public int[] prod(int[] arr) {
int[] result = new int[arr.length];
prod(arr, result, 0, 1);
return result;
}
private int prod(int[] arr, int[] result, int i, int left) {
if (i >= arr.length) {
return 1;
}
int right = prod(arr, result, i + 1, left * arr[i]);
result[i] = left * right;
return right * arr[i];
}
也可以使用2个for循环完成:
public int[] prod(int[] arr) {
int[] result = new int[arr.length];
for (int i = 0, left = 1; i < arr.length; left *= arr[i++]) {
result[i] = left;
}
for (int i = arr.length - 1, right = 1; i >= 0; right *= arr[i--]) {
result[i] *= right;
}
return result;
}
请用多个短句解释这个问题。“不清楚你想达到什么目的。@迈克尔,先生,问题描述补充道。但是我能不能在O(n)
??@LoganPaul中找到一个没有除法的解决方案?”?我不确定,但不使用流API。我不确定调用递归解决方案是简单还是简单。至少,我知道我不会在生产代码中使用HotSpot JVM尝试递归深度等于数组大小…@Holger完全同意你的观点。因为这是一个练习——到目前为止,在任何工作的项目中从未有过这样的要求——我会尝试递归。
public int[] prod(int[] arr) {
int[] result = new int[arr.length];
prod(arr, result, 0, 1);
return result;
}
private int prod(int[] arr, int[] result, int i, int left) {
if (i >= arr.length) {
return 1;
}
int right = prod(arr, result, i + 1, left * arr[i]);
result[i] = left * right;
return right * arr[i];
}
public int[] prod(int[] arr) {
int[] result = new int[arr.length];
for (int i = 0, left = 1; i < arr.length; left *= arr[i++]) {
result[i] = left;
}
for (int i = arr.length - 1, right = 1; i >= 0; right *= arr[i--]) {
result[i] *= right;
}
return result;
}
public int[] prod(int[] arr) {
long product = Arrays.stream(arr).asLongStream().reduce(1L, (a, b) -> a * b);
return Arrays.stream(arr).map(a -> (int) (product / a)).toArray();
}