Reputation: 127
So, for example i have an array: int[] {1,2,3,4,5}
. I need to print the product of even positions, 0 position will be considered even, so it will be: 1 * 3 * 5 = 15
.
When I am summing an array, I am doing something like this:
int sum = 0;
for (int i = 0; i < arr.length; sum += arr[i++])
and I am receiving the answer correct.
Now, I thought of using the same method for getting the product:
int produs = 1;
for (int i = 0; i < arr.length; produs *= arr[i = i + 2])
Here I always get an error. I don't know why, but if I am doing:
int produs = 1;
for (int i = 0; i < arr.length; i++) {
if ( (i & 1) == 0) {
produs *= arr[i];
}
}
or
int produs = 1;
for (int i = 0; i < arr.length; i = i + 2) {
produs *= arr[i];
}
I am also getting correct answer.
so, my question is why my method with inline for does not work?
int produs = 1;
for (int i = 0; i < arr.length; produs *= arr[i = i + 2])
this one.
Upvotes: 0
Views: 194
Reputation: 947
You had better use stream
java.util.concurrent.atomic.AtomicInteger index = new java.util.concurrent.atomic.AtomicInteger();
int produs = java.util.Arrays.stream(new int[] {1,2,3,4,5})
.filter(i -> index.getAndIncrement() % 2 == 0).reduce(1, (a, b) -> a * b);
Upvotes: -1
Reputation: 2575
If you perform a suffix increment operation, the compiler puts the old value on the stack, e.g.
int[] arr = new int[] { 0, 10, 20, 30 };
int i = 0;
int x = arr[i++]; // x will be 0, i is incremented to 1
On the other hand, if you would use a prefix increment operation, the compiler puts the new value on the stack, e.g.
int[] arr = new int[] { 0, 10, 20, 30 };
int i = 0;
int x = arr[++i]; // x will be 10, i is incremented to 1
Lastly, a variable assignment operation puts the resulting value on the stack, e.g.
int[] arr = new int[] { 0, 10, 20, 30 };
int i = 0;
int x = arr[i = i + 3]; // x will be 30, i is increased by 3
Therefore, if you use arr[i = i + 2]
as post-block statement, you actually access the following array elements: 2, 4, 6
, yielding an ArrayIndexOutOfBoundsException
.
I strongly recommended (also for the sake of readability) that you restructure your algorithm to use the for
-block to do the actual calculation and to use the post-block statement to increase the variable i
:
for (int i = 0; i < arr.length; i+=2) {
// TODO Calculation
}
Upvotes: 6
Reputation: 19926
You run into an ArrayIndexOutOfBoundsException
, because you try to access an element beyond the array boundary. That is because the condition i < arr.length
will not be checked when you do produs *= arr[i = i + 2]
in the last section of the for
-loop.
You can just split up your code inside the increment section, in fact you can chain as many statements in there as you wish, you just have to separate them with a comma ,
:
int produs = 1;
for (int i = 0; i < arr.length; produs *= arr[i], i += 2);
Upvotes: 1
Reputation: 49
The reason you cannot implement a for-loop like this inline is that in the incremental part produs *= arr[i = i + 2]
you will have i
reaching an index out of the bound of your array because it jumps through 2 steps. Basically in its final iteration, i
will reach value of 6 which is out of the indices of your array (the final index of your array is 4) and the part produs *= arr[i = i + 2]
will produce an error.
In this case, it is better to use the way that worked for you:
int produs = 1;
for (int i = 0; i < arr.length; i = i + 2) {
produs *= arr[i];
}
Upvotes: 0
Reputation: 7873
You always instantiate your produs
with 0
.
If you multiply something with zero, than it will be zero.
You have to instantiate it with 1
, then should your last example work
int produsOfEven(int[] array) {
int produs = 1;
// step by 2
for (int i = 0; i < array.length; i += 2) {
produs *= array[i];
}
return produs;
}
To your question, why the last example wont work: As already pointed out in the comments, your condition will be checked to "late".
Let us imagine you have the code for (int i = 0; i < arr.length; produs *= arr[i = i + 2])
and array of length 3. Then this steps will be computed:
i
with 0
.i < arr.length
, it is true.i
by running produs *= arr[i = i + 2]
, i
is now 2
, produs
is changed by array-index 2
.i < arr.length
, it is true.i
by running produs *= arr[i = i + 2]
, i
is now 4
, produs
is changed by array-index 4
. ArrayIndexOutOfBoundsException
was thrown.Upvotes: -1