iftwMZ
iftwMZ

Reputation: 127

Java arrays produs of even positions

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

Answers (5)

Miller Cy Chan
Miller Cy Chan

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

trylimits
trylimits

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

Lino
Lino

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

Enver Umerov
Enver Umerov

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

akop
akop

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;
}

Edit

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:

  1. Init i with 0.
  2. Check condition i < arr.length, it is true.
  3. Exec body - no body, nothing will happen.
  4. Increase i by running produs *= arr[i = i + 2], i is now 2, produs is changed by array-index 2.
  5. Check condition i < arr.length, it is true.
  6. Exec body - no body, nothing will happen.
  7. Increase i by running produs *= arr[i = i + 2], i is now 4, produs is changed by array-index 4. ArrayIndexOutOfBoundsException was thrown.

Upvotes: -1

Related Questions