ArrayIndexOutOfBoundsException error in method for finding greatest common divisor

40 Views Asked by At

Purpose is to find greatest common divisor of numbers: 45 & 75 which is 15. I get ArrayIndexOutOfBoundsException on line with while loop. Could you please help. I don't understand why? Parameter has to be variable-length argument lists. At the moment I have 2 numbers just to check if gcd is calculated correctly later array will need to be 5 long.

public static int gcd (int... numbers) {

        //initial greatest common divisor is 1
        int gcd = 1;

        //possible greatest common divisor is 2
        int k = 2;

        //looping through array with test input of 2: 45 & 75
        int i, j;
        for (i = 0; i <= numbers.length - 1; i++) {
            for (j = i + 1; j <= numbers.length; j++) {
                while (k <= numbers[i] && k <= numbers[j]) {
                    if (numbers[i] % k == 0 && numbers[j] % k == 0)
                        //update
                        gcd = k;

                    k++;
                }
            }
        }
        return gcd;
    }

All I need to do is to compare first element with next one, second with next one etc. so hence created 2 for loops. In while loop greatest common divisor is being calculated. But I am stuck to understand what I am doing wrong. Would appreciate a hint or guidance.

This is correct method from the book to calculate gcd but not with array:

public static int gcd(int n1,int n2) {
    int gcd = 1; // Initial gcd is 1
    int k = 2; // Possible gcd

    while (k <= n1 && k <= n2) {
        if (n1 % k == 0 && n2 % k == 0)
           gcd = k; // Update gcd
        k++;
    }

    return gcd; // Return gcd
 }
2

There are 2 best solutions below

0
Andrew Lazarus On

C-derived languages (C, C#, Java, C++) all start arrays at zero, which means the last element is my_array[my_array.length-1], however that is written exactly in that language. So the idiom in a loop is generally

for (int i = 0; i < my_array.length; ++i) /* do something */

however the length is obtained in the language. Note that your code has <=, which is almost always wrong.

Euclid had a more efficient way of getting gcd 2300 years ago; you might look for it.

I tell learners that C, Java, etc. are like England, France, and Quebec, where you enter a building on the ground floor (sometimes marked 0 in an elevator) and climb stairs to the first floor. Pascal, SQL, and IIRC Visual Basic start arrays at 1 (so <= is correct to get to the end of an array), like the USA and Anglophone Canada, you walk into the first floor. People are welcome to add other countries in the comments.

0
gambinaattori On

Your inner for-loop allows j to be equal to numbers.length:

for (j = i + 1; j <= numbers.length; j++) {

Then you try to reference numbers[j]:

while (k <= numbers[i] && k <= numbers[j]) {
    if (numbers[i] % k == 0 && numbers[j] % k == 0)

The last element in numbers is numbers[numbers.length - 1]. The exception happens when you try to access an element that is beyond the final element in the array, i.e. when j == numbers.length.