Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Fallo en programa que muestra la frecuencia aparece caras de un dado

Estas en el tema de Fallo en programa que muestra la frecuencia aparece caras de un dado en el foro de C/C++ en Foros del Web. Hola, tengo un problema con un ejercicio que estoy realizando en C++. Les cuento, tengo que escribir un programa que simule 10 000 000 de ...
  #1 (permalink)  
Antiguo 19/09/2010, 12:30
 
Fecha de Ingreso: septiembre-2010
Mensajes: 6
Antigüedad: 13 años, 7 meses
Puntos: 0
Fallo en programa que muestra la frecuencia aparece caras de un dado

Hola, tengo un problema con un ejercicio que estoy realizando en C++. Les cuento, tengo que escribir un programa que simule 10 000 000 de tiradas de un dado e imprima las frecuencias que se obtienen para cada una de las caras.

Mi propuesta para resolver este ejercicio es:
Código c++:
Ver original
  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <ctime>
  4. using namespace std;
  5.  
  6. //Función que genera un número pseudoaleatorio entero en el intervalo discreto [a, b].Conseguir un entero entre [a,b] es igual a conseguirlo
  7. //entre a + [0, b-a]. Para conseguir enteros entre 0 y b-a recurrimos al resto de la división entera, ya que el resto de dividir cualquier
  8. //número entre b-a+1 nos da valores entre 0 y b-a, a los cuales les sumaremos el valor a obteniendo así enteros del intervalo [a, b].
  9. int Numero_Pseudoaleatorio(int a, int b){
  10.   return a+(rand()%(b-a+1));
  11. }
  12.  
  13. int main()
  14. {
  15.   const int a=1, num_caras = 6;
  16.   const float num_tiradas = 10000000;
  17.   int v[num_caras], num_pseudo = 0;
  18.  
  19.   for(int i=1; i<=num_caras; i++)     // Inicializamos el vector a 0
  20.     v[i]=0;
  21.  
  22.   srand(time(0));   // Usaremos como semilla un valor variable para poder observar distintos resultados en cada ejecución.
  23.  
  24.   for(int i=1; i<=num_tiradas; i++){    //realizamos las 10000000 tiradas del dado
  25.     num_pseudo = Numero_Pseudoaleatorio(a,num_caras);   //almacenamos el resultado de la tirada (valor de la cara del dado)
  26.     v[num_pseudo]++;    //incrementamos las veces que aparece cada valor.
  27.    
  28.   }
  29.   cout << "****muestra el número de veces que aparece cada cara****" << endl;
  30.   cout << "cara   1  -----> " << v[1] << endl;
  31.   cout << "cara   2  -----> " << v[2] << endl;
  32.   cout << "cara   3  -----> " << v[3] << endl;
  33.   cout << "cara   4  -----> " << v[4] << endl;
  34.   cout << "cara   5  -----> " << v[5] << endl;
  35.   cout << "cara   6  -----> " << v[6] << endl;
  36.  
  37.  
  38.   float suma = 0;
  39.  
  40.   for(int i=1; i <=num_caras; i++){  /* EN ESTE BUCLE ESTA EL PROBLEMA, ¿PORQUE V[6] CAMBIA SU VALOR? */
  41.     cout<< "cara 6 -->" << v[6] << endl;  /*HAGO ESTO PARA COMPROBAR QUE V[6] CAMBIA SU VALOR AL ENTRAR EN EL BUCLE Y SE VA INCREMENTANDO*/
  42.    
  43.     cout << "La frecuencia relativa de " << i << " es: " << v[i]/num_tiradas << endl;
  44.    
  45.     suma = suma + v[i]/num_tiradas;
  46.     cout << " frecuencia absoluta = " << suma << endl;
  47.    
  48.   }
  49.  
  50. }

pero cuando obtengo los resultados, veo que en el último bucle for cambia el valor de v[6] en cada iteración y realmente no entiendo porqué sucede esto.

Al final la frecuencia absoluta no me sale 1, por lo que se que el problema esta mal.

Espero que puedan ayudarme.
Muchas gracias y un saludo.
  #2 (permalink)  
Antiguo 19/09/2010, 13:29
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 15 años, 10 meses
Puntos: 61
Respuesta: Fallo en programa que muestra la frecuencia aparece caras de un dado

Los indices de los arreglos son validos desde 0 hasta el tamaño - 1, no desde 1 al tamaño.
  #3 (permalink)  
Antiguo 19/09/2010, 18:29
 
Fecha de Ingreso: septiembre-2010
Mensajes: 6
Antigüedad: 13 años, 7 meses
Puntos: 0
Respuesta: Fallo en programa que muestra la frecuencia aparece caras de un dado

Muchas gracias CalgaryCorpus por tu contestación, ya lo he solucionado y funciona perfectamente, pero ¿me podrías indicar a que es debido esto? es decir ¿qué diferencia hay entre poner de 1 a tamaño ó poner de 0 a tamaño-1?
Saludos.
  #4 (permalink)  
Antiguo 19/09/2010, 19:17
Avatar de carlos_belisario
Colaborador
 
Fecha de Ingreso: abril-2010
Ubicación: Venezuela Maracay Aragua
Mensajes: 3.156
Antigüedad: 14 años
Puntos: 461
Respuesta: Fallo en programa que muestra la frecuencia aparece caras de un dado

bueno si te fijas los indices de los arreglos van desde el 0 hasta el tamaño -1 entonces si kieres recorrer los valores de un vector debes de hacerlo igual ya que si lo haces comenzando desde 1 hasta el tamaño estarias obviando el primer indice y teniendo una entrada de mas en el ciclo ya que la ultima accion no haria nada al vector espero que me alla explicado bien saludos
__________________
aprende d tus errores e incrementa tu conocimientos
it's not a bug, it's an undocumented feature By @David
php the right way
  #5 (permalink)  
Antiguo 19/09/2010, 19:37
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: Fallo en programa que muestra la frecuencia aparece caras de un dado

Es normal empezar en cero por una cuestion aritmetica. Un array no es unas que un bloque de memoria. La memoria puede ser accedida mediante un numero.

Con los array se tiene el numero inicial del bloque y luego segun la posicion que se desea se suma un offset.
Por ejemplo supongamos que tenemos un array en la posicion 100. Entonces el primer elemento va a estar en 100+ 0 = 100
La segunda posicion va a ser 100+1 = 101...

Como te puedes imaginar para indice i la cuenta seria 100 + i... Por eso en c se empieza desde el cero ya que facilita el estas cuentas!!!

Pero que se entienda!
  #6 (permalink)  
Antiguo 20/09/2010, 02:06
 
Fecha de Ingreso: junio-2010
Ubicación: Madrid
Mensajes: 620
Antigüedad: 13 años, 10 meses
Puntos: 73
Respuesta: Fallo en programa que muestra la frecuencia aparece caras de un dado

En C, los índices para los arrays van siempre desde 0 a N-1, no como otros lenguajes (por ejemplo, PASCAL permite indicar el primero y el último, y el antiguo intérprete BASIC de MS-DOS permitía elegir entre 0 y 1). La razón no era más que simplificar el trabajo del compilador, piensa que en los primeros ordenadores la memoria era un bien muy escaso y muy caro y había que arañar cada byte, tanto de código como de datos.
  #7 (permalink)  
Antiguo 20/09/2010, 04:06
 
Fecha de Ingreso: septiembre-2010
Mensajes: 6
Antigüedad: 13 años, 7 meses
Puntos: 0
Respuesta: Fallo en programa que muestra la frecuencia aparece caras de un dado

Muchas gracias a todos, ya lo he entendido perfectamente.
A continuación dejo la solución ya corregida.
Código C++:
Ver original
  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <ctime>
  4. using namespace std;
  5.  
  6. //Función que genera un número pseudoaleatorio entero en el intervalo discreto [a, b].Conseguir un entero entre [a,b] es igual a conseguirlo
  7. //entre a + [0, b-a]. Para conseguir enteros entre 0 y b-a recurrimos al resto de la división entera, ya que el resto de dividir cualquier
  8. //número entre b-a+1 nos da valores entre 0 y b-a, a los cuales les sumaremos el valor a obteniendo así enteros del intervalo [a, b].
  9. int Numero_Pseudoaleatorio(int a, int b){
  10.   return a+(rand()&#37;(b-a+1));
  11. }
  12.  
  13. int main()
  14. {
  15.   const int a=1, num_caras = 6;
  16.   const float num_tiradas = 10000000;
  17.   int v[num_caras], num_pseudo = 0;
  18.   for(int i=0; i<=num_caras-1; i++)     // Inicializamos el vector a 0
  19.     v[i]=0;
  20.   srand(time(0));   // Usaremos como semilla un valor variable para poder observar distintos resultados en cada ejecución.
  21.   for(int i=0; i<=num_tiradas-1; i++){  //realizamos las 10000000 tiradas del dado
  22.     num_pseudo = Numero_Pseudoaleatorio(a,num_caras);   //almacenamos el resultado de la tirada (valor de la cara del dado)
  23.     v[num_pseudo-1]++;  //incrementamos las veces que aparece cada valor.
  24.   }
  25.   for(int i=0; i<=num_caras-1; i++){ //mostramos las frecuencias relativas.
  26.     cout << "La frecuencia relativa de " << i << " es: " << v[i]/num_tiradas << endl;
  27.   }
  28. }

Saludos.

Etiquetas: dado, fallo, frecuencia, muestra, programa
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 18:46.