¿De dónde obtiene este programa sus números y por qué esto es causado por el aumento del tamaño de 1 matriz? (Java)

StackOverflow https://stackoverflow.com/questions/8335998

Pregunta

Se supone que este programa simplemente elimina los duplicados de una matriz. Sin embargo, el segundo para el bucle en el método de eliminación fue arrojar una excepción fuera de los límites. Estaba mirando y no podía ver cómo podría ser eso, así que pensé que aumentaría el tamaño de la matriz en 1 para que funcionara con el único inconveniente de ser un 0 extra pegado al final.

Para mi sorpresa, cuando aumenté el tamaño del rastreador [] de 10 a 11, el programa imprime cada número de 0 a 9, incluso si no impulso la mayoría de esos números. ¿De dónde vienen esos números y por qué tengo este problema?

import java.util.*;
class nodupes 
{
    public static void main(String[] args) 
    {   

        int[] dataset = new int[10];


        //getting the numbers
        for (int i = 0; i <= 9 ; i++)
        {
            Scanner input = new Scanner(System.in);
            System.out.println("Enter a one digit number");
            dataset[i] = input.nextInt();
        }

        int[] answer = (eliminateduplicates(dataset));
        System.out.println(Arrays.toString(answer));
    }

    public static int[] eliminateduplicates(int[] numbers)
    {

        boolean[] tracker = new boolean[11];
        int arraysize = 1; 
        for(int k = 0; k <= 9; k++)
        {

            if(tracker[numbers[k]] == false)
            {
                arraysize++;
                tracker[numbers[k]] = true;
            }

        }
        int[] singles = new int[arraysize];

        for(int l = 0; l <= arraysize; l++)
        {
            if(tracker[l] == true)
            {
                singles[l] = l;

            }


        }

        return singles;
    }
}    

La excepción estaba ocurriendo en esta parte

     if(tracker[l] == true)

Pero solo cuando el tamaño de los rastreadores era 10. a las 11 solo imprime [0,1,2,3,4,5,6,7,8,9

EDITAR: El conjunto de matrices = 1 fue un control de la depuración, originalmente estaba a las 0

Editar: lo arregló, pero ahora hay un 0 al final, a pesar de que la matriz debería estar completamente llena.

public static int[] eliminateduplicates(int[] numbers)
{

    boolean[] tracker = new boolean[10];
    int arraysize = 0; 

    for(int k = 0; k < numbers.length; k++)
    {

        if(tracker[numbers[k]] == false)
        {
            arraysize++;
            tracker[numbers[k]] = true;
        }

    }
    int[] singles = new int[arraysize];
    int counter = 0;

    for(int l = 0; l < arraysize; l++)
    {
        if(tracker[l] == true)
        {
            singles[counter] = l;
            counter++;
        }


    }

    return singles;
}
¿Fue útil?

Solución

Editar como 20 porque realmente debería estar dormido. Al darme cuenta de que probablemente acabo de hacer su tarea por usted, así que eliminé el código.

Arraysize debe comenzar en 0, porque comienza sin números y comienza a agregar a este tamaño a medida que encuentra duplicados. Suponiendo que solo había 1 número repetido diez veces, habría creado una matriz de tamaño 2 para almacenar 1 número. int arraysize = 0;

Su primera para bucle debe recorrer numbers, por lo que tiene sentido usar la longitud de los números en la restricción del bucle. for( int i = 0; i < numbers.length; i ++)

Para el segundo para el bucle: debe atravesar todo tracker matriz, por lo que bien podría usar la longitud para eso (tracker.length). Menos números mágicos siempre son algo bueno. También necesita otras variables para realizar un seguimiento de su lugar en el singles formación. Si los números fueran una matriz de 10 9s, entonces solo el rastreador [9] sería cierto, pero esto debería colocarse en singles [0]. Nuevamente, un mal trabajo de mi parte de explicar, pero es difícil sin diagramas.

Derp derp, tengo ganas de ser amable/ir a la cama, así que, listo, el código que usé (funcionó la única vez que intenté probarlo):

public static int[] eliminateduplicates(int[] numbers)
{
    boolean[] tracker = new boolean[10];
    int arraysize = 0; 

    for(int k = 0; k < numbers.length; k++)
    {
        if(tracker[numbers[k]] == false)
        {
            arraysize++;
            tracker[numbers[k]] = true;
        }
    }

    int[] singles = new int[arraysize];

    for(int l = 0, count = 0; l < tracker.length; l++)
    {
        if(tracker[l] == true)
        {
            singles[count++] = l;
        }
    }

    return singles;
}

Otros consejos

Dado que las matrices comienzan en 0, su arraysize será uno mayor que el número de números únicos, por lo que su bucle final pasa demasiadas veces. En otras palabras, "L" (letra L: intente usar un nombre de variable diferente) llegará a 11 si tiene 10 números únicos y el rastreador solo tiene el elemento 0-10, por lo tanto, una excepción fuera de límites. Intente cambiar la declaración a int ArraySize = 0;

Una vez más derrotado por <=

for(int l = 0; l <= arraysize; l++)

Un tamaño de matriz de 10 significa 0-9, este bucle irá 0-10

Para de dónde vienen los números,

singles[l] = l;

está asignando los valores de conteo en campos individuales, por lo que se asignan solteros [1] 1, etc.

Siento que está haciendo demasiado procesamiento para obtener un duplicado, si no tiene la restricción de no usar colecciones, entonces puede probar esto

public class NoDupes {
    public static void main(String[] args) {
        Integer[] dataset = new Integer[10];
        for (int i = 0; i < 10; i++) {
          Scanner input = new Scanner(System.in);
          System.out.println("Enter a one digit number");
          dataset[i] = input.nextInt();
        }
        Integer[] arr = eliminateduplicates(dataset);
        for (Integer integer : arr) {
           System.out.println(integer);
        }
    }

     public static Integer[] eliminateduplicates(Integer[] numbers) {
        return new HashSet<Integer>(Arrays.asList(numbers)).toArray(new Integer[]{});
     }
}

Para responder a su pregunta, su bucle final va a un índice más que el tamaño.

El rango de índices válidos en una matriz en Java es [0, SIZE), es decir. de 0 a arraysize-1.

La razón por la que obtienes la excepción es porque en tu bucle estás iterando de 0 a arraysize inclusivamente, 1 índice demasiado lejos:

for(int l = 0; l <= arraysize; l++)

Por lo tanto, cuando llegas a if(tracker[l] == true) en la última iteración, l será igual a arraysize y tracker[l] estará fuera de los límites de la matriz. Puedes solucionar esto fácilmente cambiando <= a < en tus for condición de bucle.


La razón por la que el problema desaparece cuando el tamaño de su matriz se cambia de 10 a 11 tiene que ver con arraysize ser incrementado hasta 10 en el for Luce por encima del que causa los problemas. Esta vez, singles[10] es un elemento válido en la matriz ya que el rango de índices en su matriz es ahora [0, 11).

EDITAR: Realmente arraysize tiene el potencial de ser incrementado a 11, pensé que se inicializó a 0 en cuyo caso solo llegaría a 10. De cualquier manera, lo anterior sigue siendo válido; El último índice que intenta acceder en su matriz debe ser 1 menos que la longitud de su matriz para evitar la excepción que está recibiendo, ya que las matrices están basadas en cero. Así que sí, larga historia corta, <= debiera ser <.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top