Error in indexes of an array

2

I'm trying to make a selection sort algorithm, just to train algorithms myself, to my see my logic is right about sorting, but it's returning me an error 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 complete error 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.2\executor-snippets\run.xml:53: Java returned: 1
FALHA NA CONSTRUÇÃO (tempo total: 5 segundos)

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

  

confusing primitive array specified for the vararg method.

    
asked by anonymous 27.12.2018 / 18:21

3 answers

3

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[] ( of% arrays), 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 int to get the class of each element in the list, and then I use method getClass() , which checks if the class in question represents an array. The output is:

  

true

isArray() is printed only once, since the list returned by true has only one element: the array of Arrays.asList . If you'd like, you can check the size of the list using int :

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

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

Anyway, since the elements in this list are arrays, int will not find the indexOf you're passing. int checks if indexOf is an element of the list, but because the list only has an array as element, int is not found (the fact that int is inside the array does not matter, int you will not find indexOf ).

And when it does not find the element, 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 ( int , where vet[idx] is -1), the idx error occurs since the positions of an array start at zero (there are no positions negative).

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 run it through each iteration (besides being unnecessary, it is extremely inefficient to create a new list at each iteration).

If you set the value of the index when the smallest element is found, you do not need to create the list at any 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;
}

Notice also that I gave a change in the algorithm, and also put the name of the method starting with a lowercase letter, following the Java code conventions .

    
27.12.2018 / 18:50
2

Well, this means that you are trying to get the element that is in the "-1" index, but it does not exist
What's happening:

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

So in this line vet[idx] = aux; is giving the exception ArrayIndexOutOfBoundsException which informs that an element is being accessed in an index that does not exist, since the array starts at 0 it does not have access to -1.

To solve this I suggest saving 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];

To:

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

So you do not need to convert the array to list and find the value again (which by the way is much more costly, why look for the information that is slightly higher in the code?)

    
27.12.2018 / 18:48
0

In the Arrays.asList (vet) .indexOf (smaller) line the indexOf was not finding the smallest 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]);
           }
    }
}
    
27.12.2018 / 19:16