• Jueves 25 de Abril de 2024, 04:21

Autor Tema:  Llenar arreglo con serie aleatoria del 1 al 10  (Leído 22384 veces)

pedroqv

  • Miembro activo
  • **
  • Mensajes: 55
    • Ver Perfil
Llenar arreglo con serie aleatoria del 1 al 10
« en: Jueves 17 de Diciembre de 2009, 21:02 »
0
Desarrolle este algoritmo para llenar un arreglo del 1 al 10 de forma aleatoria sin que se repitan los numeros, pero casi siempre hay un numero que se repite, violando mi condicion if.

Código: C#
  1.  
  2.  int[] aux = new int[10];
  3.  Random r = new Random();
  4.             for (int i = 0; i < 10; i++)
  5.             {
  6.                 int num = r.Next(0, 10);
  7.                 for (int j = 0; j < 10; j++)
  8.                 {
  9.                     if (aux[j] == num)
  10.                     {
  11.                         num = r.Next(0, 10);
  12.                         j = 0;
  13.                     }
  14.                 }
  15.                 aux[i] = num;
  16.                 write(num);
  17.             }
  18.  
  19.  

Ejemplo de serie esperada: 3  2  5  7  9  8  1  4  6  0
Ejemplo de serie real: 4  5  9  0  1  3  4  2  7  6

 :alien:   :alien:   :alien:

ProfesorX

  • Moderador
  • ******
  • Mensajes: 796
  • Nacionalidad: mx
    • Ver Perfil
Re: Llenar arreglo con serie aleatoria del 1 al 10
« Respuesta #1 en: Jueves 17 de Diciembre de 2009, 22:32 »
0
Eso es porque el algoritmo que estas usando no es correcto.

La clase Random genera un numero nuevo cada vez, pero no garantiza que el numero generado no se repita.

Lo que necesitas es un algoritmo parecido a los que se utilizan para barajar las cartas.

Te dejo un codigo que adapte de http://casidiablo.net/codigo-ejemplo-didactico-con-strings-en-java-simulacion-para-barajar-y-repartir-cartas/ para barajar cartas. Antes de usarlo, deberas llenar tu vector con los numeros del 0 al 9, y ya despues llamar al metodo barajar.

Código: C#
  1.  
  2.         static void barajar()
  3.         {
  4.             Random r = new Random();
  5.  
  6.             // Para cada carta, elegir otra carta aleatoria e intercambiarlas
  7.             for (int primera = 0; primera < aux.Length; primera++)
  8.             {
  9.                 int segunda = r.Next(0, 10);
  10.                 int temp = aux[primera];
  11.                 aux[primera] = aux[segunda];
  12.                 aux[segunda] = temp;
  13.             }
  14.         }
  15.  
  16.  

Saludos :)

NOTA:
==================================================================
Este foro es para ayudar, aprender, compartir... usenlo para eso,
NO SE RESUELVEN DUDAS POR MENSAJE PRIVADO Y MENOS POR CORREO
==================================================================

pedroqv

  • Miembro activo
  • **
  • Mensajes: 55
    • Ver Perfil
Re: Llenar arreglo con serie aleatoria del 1 al 10
« Respuesta #2 en: Viernes 18 de Diciembre de 2009, 00:20 »
0
Si eso eh cierto la clase Random me esta generando un numero del 0 al 9, al pasarle parametros (0,10) pero dentro del ciclo anidado for tengo una condicion el cual cuando se genera un numero aleatorio verifica que no haya otro igual en ese vector si no lo haya lo introduce, y si encuentra otro igual genera otro numero aleatorio y empieza de nuevo a recorrer todo el arreglo hasta que el numero generado no se ha encontrado, pero algo pasa y a veces si aparece un numero repetido, como qeu se atonta el if

ProfesorX

  • Moderador
  • ******
  • Mensajes: 796
  • Nacionalidad: mx
    • Ver Perfil
Re: Llenar arreglo con serie aleatoria del 1 al 10
« Respuesta #3 en: Viernes 18 de Diciembre de 2009, 02:51 »
0
Cita de: "pedroqv"
como qeu se atonta el if

Mas bien los que nos atontamos somos los programadores  :rolleyes:

Bueno, yo sigo diciendo que el algoritmo que quieres usar no es muy eficiente, ya que cada vez que generas un numero nuevo, buscas dentro de todo el vector, para verificar que el numero no se repita.

Aun asi, revise tu codigo mas detenidamente, pero antes de decirte que tienes mal, te dare otro consejo.

Trata de usar el depurador de Visual Studio, es muy facil de usar, y te ayudara a encontrar esos pequeños errores que se nos escapan.

En especial, usa el Paso por instrucciones (tecla F11) y el Paso por procedimentos (F10) ademas de la inspeccion de variables, y ejecuta paso por paso tu programa en las partes mas citicas, y cuando hayas depurado ciertas partes, utilza puntos de interrupcion, para que tu progama se detenga solo en ciertas partes, y depures mas facil, todo esto combinado con la inspeccion de variables como dije antes.

Bueno, ahora si, vamos al fondo del problema :)

El problema es esta instruccion, o sea, el ciclo que revisa el vector desde el principio para verificar que no haya repetidos:
Código: C#
  1.  
  2.                 for (int j = 0; j < 10; j++)
  3.  
  4.  

1. Para empezar, la condicion j < 10 es incorrecta, ya que revisas todo el vector aun cuando este no esta lleno todavia, lo mas correcto seria revisar solo hasta donde hayamos leido, o sea la condicion seria j < i.

2. El orden de evaluacion del ciclo for es como sigue:

a. Inicializa la variable j (j = 0)
b. Pregunta si j < 10, si es verdadero entra al ciclo, si es falso, sale del ciclo.
c. cuerpo del ciclo.
d. incrementa j y regresa al paso b.
e. salida del ciclo

Por lo tanto, dentro de tu ciclo, cuando tu haces:
Código: C#
  1.  
  2.                    if (aux[j] == num)
  3.                     {
  4.                         num = r.Next(0, 10);
  5.                         j = 0;
  6.                     }
  7.  
  8.  

Tu regresas j a cero, pero despues de eso, el for incrementa j antes de preguntar si j < 10, por lo tanto, cuando entra al ciclo, en realidad j vale 1 y no cero como podrias suponer, asi que se salta el primer elemento en la comparacion de repetidos. Entonces si random te repite el numero que esta en la primera posicion del vector, no te lo cambia, porque el for se salta el primer elemento. De hecho si ejecutas el programa, veras que el numero que se repite cuando se llega a repetir, siempre es el de la primera posicion. (en tu ejemplo es el 4 el que esta en la primera, y ese es precisamente el que se repite  :lol:)

La solucion correcta entonces seria usar un ciclo while en lugar de un ciclo for, e incrementar la variable j, solamente cuando el numero no este repetido

Código: C#
  1.  
  2.                     int j = 0;
  3.                     while (j < i)
  4.                     {
  5.                         if (aux[j] == num)
  6.                         {
  7.                             num = r.Next(0, 10);
  8.                             j = 0;
  9.                         }
  10.                         else
  11.                         {
  12.                             j++;
  13.                         }
  14.                     }
  15.  
  16.  

Pruebalo y veras que ahora si funciona correctamente.

Todo esto lo encontre usando las opciones de depuracion de Visual Studio, asi que sigue mi consejo y depura tu mismo con el depurador, veras que es increible.

Bueno, fue divertido mientras duro  :P

Saludos :)

NOTA:
==================================================================
Este foro es para ayudar, aprender, compartir... usenlo para eso,
NO SE RESUELVEN DUDAS POR MENSAJE PRIVADO Y MENOS POR CORREO
==================================================================

pedroqv

  • Miembro activo
  • **
  • Mensajes: 55
    • Ver Perfil
Re: Llenar arreglo con serie aleatoria del 1 al 10
« Respuesta #4 en: Viernes 18 de Diciembre de 2009, 04:49 »
0
Jeje no me habia puesto a checar ese detalle del for, pero lo que pasa que por tanto programar me estreso y no puedo hayar la solucion facil, pero igual al dia siguiente me supongo que hubiera hayado el error porque iva estar mas fresco.
Y eso de que el numero aleatorio se compara con todo el vector aunque no sea necesario lo puse asi, nomas para salir del apuro pero mas adelante lo iva a optimizar que comparara nomas los numero ya puestos.

Pero yo en el caso del ciclo anidado mantendria el uso del ciclo for bajo la condicion de que cuando el numero ya exista el valor de j tome de -1 y asi el for lo incrementa a 0 y no se salta el primer espacio del vector.

Código: C#
  1.  
  2.                    for( int j=0; j < i; j++ )   //linea corregida
  3.                     {
  4.                         if (aux[j] == num)
  5.                         {
  6.                             num = r.Next(0, 10);
  7.                             j = -1;     //linea corregida
  8.                         }
  9.                     }
  10.  
  11.  

Gracias de todos modos, resolviste y optimisaste mi algoritmo, este algoritmo lo estoy usando para ordenar de manera aleatoria las respuestas de un cuestionario cargado de la base de datos. Las repuestas se cargan a una lista, y luego aplicando el algoritmo se ordenan de manera aleatoria para que no se presenten en el mismo al usuario.

pedroqv

  • Miembro activo
  • **
  • Mensajes: 55
    • Ver Perfil
Re: Llenar arreglo con serie aleatoria del 1 al 10
« Respuesta #5 en: Viernes 18 de Diciembre de 2009, 18:55 »
0
Mi codigo anterior ni el tuyo no sirve, trate de correrlo y no sirvio pero gracias a tu consejo de depurar paso a paso encontre muy facil el error, este era que cuando inicialilo el arreglo int[] todos los valores por default son de valor 0, por lo tanto cuando falte el ultimo numero por agregar, ese va ser el 0 ya que siempre lo va hayar en el vector por que son los valores iniciales y eso va provocar un ciclo infinito.

corregido:
Código: C#
  1.  
  2. int[] aux = new int[lista.Count];            
  3.             Random r = new Random();
  4.  
  5.             for (int i = 0; i < aux.Length; i++)  //For para poner los valores en -1 del vector
  6.                 aux[i] = -1;
  7.  
  8.             for (int i = 0; i < aux.Length; i++)
  9.             {
  10.                 int num = r.Next(0, aux.Length);
  11.                 for (int j = 0; j <= i; j++)
  12.                 {
  13.                     if (aux[j] == num)
  14.                     {
  15.                         num = r.Next(0, aux.Length);
  16.                         j = -1;
  17.                     }
  18.                 }
  19.                 aux[i] = num;
  20.             }
  21.  
  22.  

pedroqv

  • Miembro activo
  • **
  • Mensajes: 55
    • Ver Perfil
Re: Llenar arreglo con serie aleatoria del 1 al 10
« Respuesta #6 en: Viernes 18 de Diciembre de 2009, 18:59 »
0
Hasta ahorita cheque el problema de barajear las cartas de tu ejemplo de Java, me complique completamente la vida, esa manera es mas sencilla y optima.

 :alien:    :alien:    :alien:

ProfesorX

  • Moderador
  • ******
  • Mensajes: 796
  • Nacionalidad: mx
    • Ver Perfil
Re: Llenar arreglo con serie aleatoria del 1 al 10
« Respuesta #7 en: Viernes 18 de Diciembre de 2009, 20:31 »
0
No quisiera decir te lo dije, pero te lo dije  :rolleyes:

Saludos :)

NOTA:
==================================================================
Este foro es para ayudar, aprender, compartir... usenlo para eso,
NO SE RESUELVEN DUDAS POR MENSAJE PRIVADO Y MENOS POR CORREO
==================================================================