Reputation: 85
I have an int[]
array with x values (x can be defined by the user), the values are random ints between 1 and 9. Now I want to create another Array with the same amount of values, and each value of the new Array is the product of all values from the other Array, except the same index.
So for example:
{4,3,5,7}
{3*5*7, 4*5*7, 4*3*7, 4*3*5} = {105, 140, 84, 60}
Here's what I have:
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;
}
The difficulty is, I have to avoid for-loops in for-loops for performance. Which is why that one block is commented-out. Dividing is not allowed.
Upvotes: 0
Views: 4082
Reputation: 1909
Another solution with java stream 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());
}
or one liner
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());
}
and explenation:
lets imagine that array as input data
List<Integer> list = List.of(2, 3, 5);
Then let's decompose the first scenario with '2', in the end, should be '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
Upvotes: 0
Reputation: 5680
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});
}
}
Output:
[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]
If the range of possible values changes you might want to change the data types of product
and the return value of multiplyArrayValues
.
Also there is no check for the values being negative or invalid. Zero will lead to a crash.
Upvotes: 0
Reputation: 43728
That's more a question about the algorithm to use. You can multiply all the numbers of the original array, lets call this p
. Now the number at position i
in the new array is p / values[i]
.
If you must not use division, you can set up two temporary arrays, one contains the product of the values with smaller or equal index, the other the product of the values with larger or equal index.
s[i] = product of v[j] where j <= i
l[i] = product of v[j] where j >= i
both arrays can be set up with a simple loop each.
Now you can calculate array[i]
as s[i-1] * l[i+1]
, taking special care of the border values. This needs also just a simple loop.
Using these ideas and doing some optimizations leads to the following code
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;
}
Upvotes: 4
Reputation: 8114
You can multiply all numbers and save it a variable(say product) , now iterate over the array using single loop and divide the product by number at each index(product/a[i]).
But since you are using integer , if the size of array is huge and also the array values is big , the product might overflow int.
Consider using Big integer i would say.
Upvotes: 1
Reputation: 18825
First multiply all the elements from the array. And then loop over all elements and divide the previously computed multiplication with current item.
Upvotes: 2