Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Gusigusa en 16 Septiembre 2017, 02:30 am



Título: calcular frecuencias de números aleatorios
Publicado por: Gusigusa en 16 Septiembre 2017, 02:30 am
Hola a todo el mundo, he credo el siguiente código en el cual se le pide al usuario cuantos números aleatorios quiere y a partir de estos se les de dos archivos donde el primero los ordene de menor a mayor y el segundo de mayor a menor, después se saque la frecuencia de dichos números, el problema es que al calcular la frecuencia me esta dando puros ceros.

Código
  1. //PROGRAMA CRISTINA!!//
  2.  
  3. #include<stdio.h>
  4. #include<stdlib.h>
  5. #include<time.h>
  6.  
  7. int i,f,g,x,p;//Estas variables son usadas en los dos FILE//
  8. int j;//Estas variables son usadas en el apartado de la frecuencia relativa//
  9.  
  10. int main ()
  11. {
  12. printf ("%4s\n%4s\n%4s\n","**********","CRISTINA","**********");
  13.  
  14. printf("¿Cuantos numeros quieres que te genere?:   ");
  15. scanf("%d",&x);
  16. printf("¿Cuantos numeros quieres que te genere?:   ");
  17. scanf("%d",&p);
  18.  
  19. int a[x],b[p], luca[x],r,s,y;//Las variables locales que seran usadas tanto para ordenar los datos como para sacar la frecuencia//
  20.  
  21. srand( time(NULL) );
  22.     for (i=0;i<=x-1;i=i+1)
  23. {
  24.     a[i]=rand();
  25.  
  26. }
  27.  
  28.  FILE *m;
  29.         m= fopen ("mayor.dat","w");
  30.  
  31. for(f=1;f<=x-1;f++) /*En este for, es importante que no se vuelva ha establecer la variable i
  32.                       pues al momento de hacer la cuenta lo confunde y no hace el ordenamiento.*/
  33.         {
  34.  
  35. for (i=0;i<=x-2;i++)
  36. {
  37.  
  38.  
  39.  
  40.                 if (a[i]<a[i+1])
  41.    {
  42.                     g=a[i];
  43.                     a[i]=a[i+1];
  44.                     a[i+1]=g;
  45.                }
  46. }
  47.         }
  48.  
  49. for (i=0;i<=x-1;i++)
  50.            {
  51. fprintf(m,"\n %4d\n",a[i]);
  52.             fprintf(m,"\n");
  53.             b[i]=a[i];
  54.             }  
  55.  
  56. fclose (m); //El primer archivo ya ha sido creado, este tiene un ordenamiento de mayor a menor//              
  57.  
  58. //Para crear el segundo ordenamiento se puede usar la misma estructura solo se cambia la desigualdad y el nombre interno der archivo//  
  59. FILE *n;
  60.         n= fopen ("menor.dat","w");
  61.  
  62. for(f=1;f<=x-1;f++)
  63.         {
  64.  
  65. for (i=0;i<=x-2;i++)
  66. {
  67.  
  68.  
  69.  
  70.                 if (a[i]>a[i+1])
  71.    {
  72.                     g=a[i];
  73.                     a[i]=a[i+1];
  74.                     a[i+1]=g;
  75.                }
  76. }
  77.         }
  78.  
  79. for (i=0;i<=x-1;i++)
  80.            {
  81. fprintf(n,"\n %4d\n",a[i]);
  82.             fprintf(n,"\n");
  83.             }  
  84.  
  85. fclose (n);    
  86. FILE *t;
  87. t=fopen("frecuencia.dat","w");
  88. for (i=0;i<x;i++){
  89. for(j=1;j<p;j++){
  90. if(a[i]==j){
  91.  
  92. y=a[i]=a[i]+1;
  93.       }
  94. }
  95.  
  96. }
  97. for (i=0;i<x;i++){
  98. fprintf(t," %7d",y);
  99.  
  100. }
  101.  
  102. fclose(t);
  103.  
  104. return 0;
  105. }  


· Los códigos deben ir en etiquetas GeSHi
· No se debe escribir en mayúsculas
>aquí las reglas del foro (http://foro.elhacker.net/reglas.htm)
-Engel Lex


Título: Re: calcular frecuencias de números aleatorios
Publicado por: Serapis en 16 Septiembre 2017, 06:54 am
A ver Cristina Gusigusa...

De entrada, no entiendo bien por qué pides dos veces la cantidad de números que se deben generar al azar...
   
Citar
printf("¿Cuantos numeros quieres que te genere?:   ");
   scanf("%d",&x);
   printf("¿Cuantos numeros quieres que te genere?:   ");
   scanf("%d",&p);

Luego parece que el array 'a', tendrá el tamaño que el usuario da a 'x', pero el array 'b' tendrá el tamaño dado a 'p'... 'x' y 'p', va a ser que no sean el mismo valor (salvo que tu misma seas quien lo introduce o rara casualidad...
Entonces si los arrays no van a ser del mismo tamaño y especialmente si no hay garantías de que el array 'b' sea mayor que el array 'a', acabará dando un error en la línea 53
Código:
b[i]=a[i];
Que además, no veo que se vuelva a usar el array 'b' en parte alguna... Luego elimina el array 'b', elimina la petición de 'p', y si no quieres eliminar 'p, al menos haz: p == x

La indentación aparece confusa, y no queda claro (de un simple vistazo), que queda dentro de qué... sin un esfuerzo extra revisando llaves (que obvio hacer)...
El ordenamiento inverso es redunndante, una vez hecho de mayor a menor o de menor a mayor, el inverso, basta con recorrer el array desde el final hacia atrás, hasta llegar a 0.

Así el código queda resumido así para menor.dat
Código:
final = x-1
Bucle para i desde final hasta 0 retrocediendo
    GuardarAfichero a(i)
fin bucle
De hecho si se abren dos canales de escritura, pueden guardarse a fichero los dos al mismo tiempo (en el mismo bucle)

Código:
Abrir Fichero 1
Abrir Fichero 2
Bucle para i desde 0 hasta x-1
    GuardarAfichero 1 a(i)   //guardando fichero mayor.dat
    GuardarAFichero 2 a(x-i) //guardando al fichero menor.dat
fin bucle
Cerrar fichero 1
Cerrar fichero 2

Aunque para ordenar usas un algoritmo de burbuja... que son muy lentos, pero para ejemplos son perfectamente válidos...

Finalmente llegamos a la parte de contar las frecuencias...
De entrada, date cuenta que si el array ya está ordenado es superfluo recorrer todo el array, las veces que un valor aparezca, estarán contiguos... ...porque el array está ordenado. Como no sabemos cuantos valores distintos hay, usaremos un bucle indefinido (Mientras... condición...repetir)

Código:
Abrir fichero
i = 0
Hacer Mientras (i<(x-1))
   v = a(i)    //valor actual para el que vamos a contar sus apariciones (absolutas).
   f = 0 // contador de apariciones [s]frecuencia[/s]
   Hacer // OJO: Este bucle tiene la condición al final,
            // esto implica que como mínimo se entra SIEMPRE una vez al bucle.
      f += 1
      i += 1
   Repetir mientras (v = a(i) )
   GuardarAFichero v, f //guardamos el valor y las veces que salió dicho valor (esto a tu gusto y necesidad)

Repetir

Si (v <> a(i)) luego  // si el último valor (en el array) no estaba repetido, el bucle no lo pilla, se hace aquí (modificar el bucle para hacerlo, hacer perder erficacia en cada cilo, algo que solo podrá ocurrir una vez en el array, asi es más óptimo dejarlo fuera (hacer esta comprobación), tras el bucle.
    GuardarAFichero a(i), 1
Fin si

Cerrar Fichero

Finalmente una aclaración... aquí se están contando el número de apariciones de cada valor, no la frecuencia. La frecuencia en realidad sería dividir el tamaño del array entre la cantidad de apariciones de cada valor... yendo más lejor se podría luego  dar en porcentaje. (con luego, no quiero decir en otro bucle si no modificarlo en otro momento).

Ojo, que como para Rand, no pones límites... si alguien pide pongamos 20 números es fácil que no se repita ninguna vez... acota Rand a un rango de valores, por ejemplo entre 100 y 110 y que la cantidad de números a generar sea (obligatorio) por lo menos el doble o el triple de lo que es el rango, para que haya 'repes'...
...es decir si 'x' (que introduce el usuario) es menor que el rango entre MinVal y MaxVal, repite la petición... MinVal y MaxVal serían los límites menor y mayor entre los que elegir al azar...


Título: Re: calcular frecuencias de números aleatorios
Publicado por: ivancea96 en 16 Septiembre 2017, 13:34 pm
Código
  1. for (i=0;i<x;i++){
  2.    fprintf(t," %7d",y);
  3. }

Aquí estás escribiendo "x" veces la misma variable "y".