An array index error

Asked

Viewed 345 times

2

I’m trying to make an algorithm for Selection Sort, just to train algorithms even, in my view my logic is right about ordering, but it is returning me an error that I do not understand.

Code:

import java.util.Scanner;
import java.util.Arrays;

public class AlgoritmosOrdenacao {


static int[] SelectionSort(int vet[]){
    int aux, menor;
    for (int i=0; i<vet.length-2; i++){
        menor = vet[i+1];
        for (int j=i+1; j<vet.length-1; j++){                
            if (menor > vet[j+1]){
                menor = vet[j+1];
            }
        }
        aux = vet[i];  
        int idx = Arrays.asList(vet).indexOf(menor);
        vet[i] = menor;            
        vet[idx] = aux;            
    }
    return vet;
}

 public static void main(String[] args) {
    // TODO code application logic here
    // INPUT DO VETOR
    int vet[] = new int[5];
   Scanner teclado = new Scanner(System.in);
   for (int i=0; i<vet.length; i++){
       vet[i] = teclado.nextInt();
   }
   // PRINT DO VETOR ANTES DA ORDENAÇÃO
   for (int z=0; z<vet.length; z++){
       System.out.printf("Vet[%d] = %d\n", z, vet[z]);
   }
   SelectionSort(vet);

   // PRINT DO VETOR DEPOIS DA ORDENAÇÃO
   System.out.println("Depois da ordenação");
   for (int z=0; z<vet.length; z++){
       System.out.printf("Vet[%d] = %d\n", z, vet[z]);
   }
}

And the whole mistake is this:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at algoritmosordenacao.AlgoritmosOrdenacao.SelectionSort(AlgoritmosOrdenacao.java:48)
at algoritmosordenacao.AlgoritmosOrdenacao.main(AlgoritmosOrdenacao.java:69)
C:\Users\angel\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
FALHA NA CONSTRUÇÃO (tempo total: 5 segundos)

On the line: int idx = Arrays.asList(vet).indexOf(menor); the Netbeans underlines vet and makes the following suggestion:

array of confused primitive specified for vararg method.

3 answers

4


The problem is in Arrays.asList(vet). When you pass an array of int, the result is a List<int[]> - that is, a list of int[] (arrays of int), and not a list of int. Example:

int v[] = { 1, 2, 3, 4, 5 };
for (Object obj : Arrays.asList(v)) {
    System.out.println(obj.getClass().isArray());
}

I’m using getClass() to obtain the class of each element in the list, and then use the method isArray(), that checks whether the class in question represents an array. The output is:

true

true is printed only once because the list returned by Arrays.asList has only one element: the array of int. If you want, you can check the list size using method size():

int v[] = { 1, 2, 3, 4, 5 };
System.out.println(Arrays.asList(v).size()); // 1

This code prints "1" as the list has only one element (the array of int).

Anyway, since the elements in this list are arrays, indexOf will not find the int that you’re going through. indexOf checks whether the int is an element of the list, but since the list only has an array as an element, the int is not found (the fact of int be inside the array no matter, indexOf will not find the int).

And when he can’t find the element, the return is -1:

int v[] = { 1, 2, 3, 4, 5 };
System.out.println(Arrays.asList(v).indexOf(2)); // -1

And when trying to access the -1 position of the array (vet[idx], whereas idx is -1), error occurs ArrayIndexOutOfBoundsException, since the positions of an array start at zero (no negative positions).


As you want to get the index of the smallest element, just set this value when you find it. There is no reason to create a new list and scroll through it every iteration (as well as being unnecessary, it is extremely inefficient to create a new list every iteration).

If you set the index value when the smallest element is found, you don’t need to create the list every time:

static int[] selectionSort(int vet[]) {
    for (int i = 0; i < vet.length - 1; i++) {
        int indiceMenor = i; // indiceMenor começa com o índice do elemento atual
        for (int j = i + 1; j < vet.length; j++) {
            if (vet[j] < vet[indiceMenor]) { // vet[j] é menor que o "menor atual"
                indiceMenor = j; // índice do menor passa a ser j
            }
        }
        int menor = vet[indiceMenor];
        vet[indiceMenor] = vet[i];
        vet[i] = menor;
    }
    return vet;
}

Note also that I changed the algorithm, and also put the name of the method starting with lowercase letter, following the Java code conventions.

  • 1

    Thank you very much for the explanation, explained me well besides having learned something new too, thank you again. = D

2

Well, that means you’re trying to get the element that’s in the index "-1", but it doesn’t exist
What’s going on:

In this line Arrays.asList(vet).indexOf(menor); the indexOf is not finding the smallest value in the list, and when it happens this function returns -1.

So on this line vet[idx] = aux; is making the exception ArrayIndexOutOfBoundsException that informs that an element is being accessed in an Index that does not exist, as the array starts at 0 has no access to the -1.

To solve this I suggest to keep the index of the lowest value, along with it.

So this line:

menor = vet[i+1];

should be modified to

menor = vet[i+1];
idxMenor = i+1;

and this line:

menor = vet[j+1];

for:

menor = vet[j+1];
idxMenor = j+1;

So you don’t need to convert the array to list and find the value again (which by the way is much more expensive, because look for the information that is a little higher in the code?)

1

In the Arrays.asList(vet) line. indexof(minor) the index was not finding the lowest value in the list and returned -1.

Try the following code to make your ordering correct:

import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class AlgoritmosOrdenacao 
{

    static int[] SelectionSort(int vetor[]){
        int aux = 0;
        for (int i = 0; i < vetor.length; i++)
        {
            for (int j = 0; j < vetor.length; j++)
            {
                if (vetor[i] < vetor[j])
                {
                    aux = vetor[i];
                    vetor[i] = vetor[j];
                    vetor[j] = aux;
                }
            }
        }
        return vetor;
    }

     public static void main(String[] args) {
            // TODO code application logic here
            // INPUT DO VETOR
            int vet[] = new int[5];
           Scanner teclado = new Scanner(System.in);
           for (int i=0; i<vet.length; i++){
               vet[i] = teclado.nextInt();
           }
           // PRINT DO VETOR ANTES DA ORDENAÇÃO
           for (int z=0; z<vet.length; z++){
               System.out.printf("Vet[%d] = %d\n", z, vet[z]);
           }
           List<int[]> a = Arrays.asList(vet);
           System.out.println();

           SelectionSort(vet);

           // PRINT DO VETOR DEPOIS DA ORDENAÇÃO 2
           System.out.println("Depois da ordenação 2");
           for (int z=0; z<vet.length; z++)
           {
               System.out.printf("Vet[%d] = %d\n", z, vet[z]);
           }
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.