calcular frecuencias de números aleatorios

Iniciado por Gusigusa, 16 Septiembre 2017, 02:30 AM

0 Miembros y 1 Visitante están viendo este tema.

Gusigusa

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.

//PROGRAMA CRISTINA!!//

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int i,f,g,x,p;//Estas variables son usadas en los dos FILE//
int j;//Estas variables son usadas en el apartado de la frecuencia relativa//

int main ()
{
printf ("%4s\n%4s\n%4s\n","**********","CRISTINA","**********");

printf("¿Cuantos numeros quieres que te genere?:   ");
scanf("%d",&x);
printf("¿Cuantos numeros quieres que te genere?:   ");
scanf("%d",&p);

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//
 
srand( time(NULL) );
    for (i=0;i<=x-1;i=i+1)
{
    a[i]=rand();
   
}
 
 FILE *m;
        m= fopen ("mayor.dat","w");
       
for(f=1;f<=x-1;f++) /*En este for, es importante que no se vuelva ha establecer la variable i
                      pues al momento de hacer la cuenta lo confunde y no hace el ordenamiento.*/
        {

for (i=0;i<=x-2;i++)
{



                if (a[i]<a[i+1])
   {
                    g=a[i];
                    a[i]=a[i+1];
                    a[i+1]=g;
               }
}
        }
       
for (i=0;i<=x-1;i++)
           {
fprintf(m,"\n %4d\n",a[i]);
            fprintf(m,"\n");
            b[i]=a[i];
            }  
   
fclose (m); //El primer archivo ya ha sido creado, este tiene un ordenamiento de mayor a menor//              

//Para crear el segundo ordenamiento se puede usar la misma estructura solo se cambia la desigualdad y el nombre interno der archivo//  
FILE *n;
        n= fopen ("menor.dat","w");
       
for(f=1;f<=x-1;f++)
        {

for (i=0;i<=x-2;i++)
{



                if (a[i]>a[i+1])
   {
                    g=a[i];
                    a[i]=a[i+1];
                    a[i+1]=g;
               }
}
        }
       
for (i=0;i<=x-1;i++)
           {
fprintf(n,"\n %4d\n",a[i]);
            fprintf(n,"\n");
            }  
   
fclose (n);    
FILE *t;
t=fopen("frecuencia.dat","w");
for (i=0;i<x;i++){
for(j=1;j<p;j++){
if(a[i]==j){

y=a[i]=a[i]+1;
      }
}

}
for (i=0;i<x;i++){
fprintf(t," %7d",y);

}

fclose(t);

return 0;
}  



· Los códigos deben ir en etiquetas GeSHi
· No se debe escribir en mayúsculas
>aquí las reglas del foro
-Engel Lex

Serapis

#1
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...
   
Citarprintf("¿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
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
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)


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)


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...

ivancea96

Código (cpp) [Seleccionar]
for (i=0;i<x;i++){
    fprintf(t," %7d",y);
}


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