我有一个带有x值的int[]
数组(x可以由用户定义),值是1到9之间的随机整数。现在我想创建另一个具有相同数值的数组,并且新数组的每个值都是来自另一个数组的所有值的乘积,但相同的索引除外。
例如:
{4,3,5,7}
{3*5*7, 4*5*7, 4*3*7, 4*3*5} = {105, 140, 84, 60}
以下是我所拥有的:
public static int[] multiplyArrayValues (int [] values) {
int array[] = new int[values.length];
for (int y = 0; y < array.length; y++) {
array[y] = 1;
}
/*for (int i = 0; i < array.length; i++) { // wrong
for (int z = 0; z < x; z++) {
if (z != i) {
array[i] = array[i] * values[z];
}
}
}*/
return array;
}
困难在于,我必须避免for循环中的for循环以提高性能。这就是为什么一个块被注释掉了。不允许分割。
答案 0 :(得分:4)
这是一个关于要使用的算法的问题。您可以将原始数组的所有数字相乘,然后调用此p
。现在,新数组中i
位置的数字为p / values[i]
。
如果你不能使用除法,你可以设置两个临时数组,一个包含索引更小或相等的值的乘积,另一个包含索引更大或相等的值的乘积。
s[i] = product of v[j] where j <= i
l[i] = product of v[j] where j >= i
两个数组都可以设置一个简单的循环。
现在,您可以将array[i]
计算为s[i-1] * l[i+1]
,特别注意边框值。这也需要一个简单的循环。
使用这些想法并进行一些优化会产生以下代码
public static int[] multiplyArrayValues (int [] values) {
int[] a = new int[values.length];
int p = 1;
for (int i = values.length - 1; i >= 0; i--) {
a[i] = p;
p *= values[i];
}
p = 1;
for (int i = 0; i < values.length; i++) {
a[i] *= p;
p *= values[i];
}
return a;
}
答案 1 :(得分:2)
首先将数组中的所有元素相乘。然后遍历所有元素并将先前计算的乘法除以当前项。
答案 2 :(得分:1)
您可以将所有数字相乘并将其保存为变量(比如产品),现在使用单循环遍历数组并在每个索引处将产品除以数字(product / a [i])。
但是由于你使用的是整数,如果数组的大小很大且数组值很大,那么产品可能会溢出int。
考虑使用我想说的大整数。
答案 3 :(得分:0)
import java.util.Arrays;
public class Main {
static int[] multiplyArrayValues(int[] values) {
int product = 1;
for(int i = 0; i < values.length; i++){
product *= values[i];
}
int[] result = new int[values.length];
for (int i = 0; i < result.length; i++) {
result[i] = product / values[i];
}
return result;
}
static void testMultiplyArrayValues(int[] values)
{
System.out.println(Arrays.toString(values) + " => " + Arrays.toString(multiplyArrayValues(values)));
}
public static void main(String[] args) {
testMultiplyArrayValues(new int[] {1,1,2,3});
testMultiplyArrayValues(new int[] {4,3,5,7});
testMultiplyArrayValues(new int[] {9,9,9,9});
testMultiplyArrayValues(new int[] {1,1,1,1});
testMultiplyArrayValues(new int[] {1,2,3,4});
}
}
输出:
[1, 1, 2, 3] => [6, 6, 3, 2]
[4, 3, 5, 7] => [105, 140, 84, 60]
[9, 9, 9, 9] => [729, 729, 729, 729]
[1, 1, 1, 1] => [1, 1, 1, 1]
[1, 2, 3, 4] => [24, 12, 8, 6]
如果可能值的范围发生变化,您可能希望更改product
的数据类型和multiplyArrayValues
的返回值。
此外,没有检查值是否定的或无效的。零会导致崩溃。
答案 4 :(得分:0)
使用Java流API的另一种解决方案
private static List<Integer> multiply(List<Integer> inputArray) {
return inputArray.stream()
.map(item ->
inputArray.stream()
.reduce(1, (a, b) -> {
if (item.equals(b))
return a;
return a * b;
}))
.collect(Collectors.toList());
}
或一支班轮
private static List<Integer> multiply(List<Integer> inputArray) {
return inputArray.stream().map(e -> (inputArray.stream().reduce(1, (a, b) -> e.equals(b) ? a : a * b))).collect(Collectors.toList());
}
和受惊症:
让我们想象一下该数组作为输入数据
List<Integer> list = List.of(2, 3, 5);
然后让我们用“ 2”分解第一个场景,最后应该是“ 15”(3 * 5)
// a = 1, a is identity (preassigned value '1' in our case - reduce(1,)...;
// 1. e = 2 - first element of the array;
// 2. e = 2, a = 1,b = 2 (first value of the array); e == b ? yes then a = a (1)
// 3. e = 2, a = 1,b = 3 (second value of array); e == b? no a * b = 1 * 3 = 3
// 4. e = 2, a = 3, b = 5 (third value of the array); e = b? no a* b = 5 * 3 = 15