salve,a tutti io avrei un problema:in questo progetto io uso l'algoritmo di ordinamento merge sort mi potreste x favore scrivere le modifiche usando al posto del merge sort il bubble sort
codice:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <limits.h>
#define DIMNF 40 //lunghezza max nome file
#define MAXPOP 1000 //dimensione max della popolazione
FILE *apriFile(char nome[])
{
FILE *file;
struct tm *dataS;
time_t dataT;
file = fopen(nome,"w");
if(file != NULL) //il file si è aperto
dataT = time(&dataT); //ggmmaa hh:mm:ss in millisecondi
dataS = localtime(&dataT);
fprintf(file, "Data: %s",asctime(dataS));
//descrizione del programma
fprintf(file,"\nIl nome dell'algoritmo che ha generato lo spazio campionario e' GeneraSpazio\n\n\n");
}
return(file);
}
/*
legge da tastiera i valori della popolazione
e li scrive sul file il cui nome è dato dall'utente
parametro char *nm: nome del file su cui scrivere
non restituisce nulla
*/
void leggiTastiera(char *nm)
{
FILE *file;
int risp;
double val;
file = fopen(nm,"w");
//leggo gli elementi fino a quando l'utente risponde no
do{
printf("dammi un valore: ");
scanf("%lf",&val);
fprintf(file,"%lf\n",val);
printf("continui? (1=si/0=no)");
scanf("%d",&risp);
} while (risp != 0);
fflush(stdin);
fclose(file);
}
/* funzioni per l'ordinamento: il MergeSort
void merge(double *X, int l, int m, int n, double *Z)
parametri: double *X vettore da ordinare
double *Z vettore ordinato
int l grandezza del vettore che sta per essere fuso
int m inizio primo testa
int n inizio seconda testa
restituisce
void mpass(double *X, double *Y, int n, int l)
parametri: double *X vettore da ordinare
double *Y vettore ausiliario
int n numero dei record
int l grandezza del vettore che sta per essere fuso
restituisce
double *MergeSort(double *X, int n)
parametri: double *X vettore da ordinare
int n numero di elementi da ordinare
restituisce il vettore ordinato di tipo double
*/
void merge(double *X, int l, int m, int n, double *Z)
{
int i=l;
int k=l;
int j=m+1;
int c;
while (i<=m && j<=n)
{if(X[i]<=X[j]) { Z[k]=X[i];
i=i+1; }
else{ Z[k]=X[j];
j=j+1;}
k=k+1;
}
if (i>m) {for(c=k;c<=n;c++) { Z[c]=X[c];}}
else { for(c=k;c<=n;c++) { Z[c]=X[c+(i-k)];}}
}
void mpass(double *X, double *Y, int n, int l)
{
int c;
int i=0;
while(i<=n-2*l+1)
{ merge(X, i, i+l-1, i+(2*l)-1, Y);
i=i+(2*l);
}
if (i+l-1<n) merge(X,i,i+l-1,n,Y);
else
{for(c=i;c<=n;c++) { Y[c]=X[c]; } }
}
double *MergeSort(double *X, int n)
{
double *Y;
Y=(double*)malloc(n*sizeof(double));
int c;
for(c=0;c<n;c++)
{ Y[c]=X[c]; }
int l=1;
while(l<n)
{ mpass(X,Y,n,l);
l=2*l;
mpass(Y,X,n,l);
l=2*l;
}
return X;
}
/*
legge i valori della popolazione e li carica in un vettore di double
parametri: char *nm: nome file da cui leggere
int *num: numerosita' popolazione
restituisce un puntatore al vettore della popolazione
*/
double *caricaPopolazione(char *nm, int *num)
{ FILE *file;
double d, *v;
int i;
file = fopen(nm,"r");
//conto gli elementi
*num = 0;
while((fscanf(file,"%lf",&d)) != EOF)
*num = *num + 1;
fclose(file);
if (*num > MAXPOP)
*num = MAXPOP;
//leggo la popolazione e la carico nel vettore v
v = (double *)malloc(*num * sizeof(double));
file = fopen(nm,"r");
for(i=0;i<*num; i++) fscanf(file,"%lf",&v[i]);
return v;
}
/*
permette la scelta di modalità di ricezione(da tastiera o da file)
dei valori della popolazione richiamando le funzione leggiTastiera e
caricaPopolazione
parametri int *numCamp: numerosità campionaria
int *numPop: numerosità della popolazione
restituisce un puntatore al vettore della popolazione
*/
double *caricaParametri(int *numCamp, int *numPop)
{ char nome[DIMNF];
double *v;
int risp, limiteDim;
//limiteDim: rappresenta la dimensione massima che può assumere il campione
printf("Generazione spazio campionario,scegli la modalita' di inserimento:");
do{
printf("\n 1=tastiera\n 2=file\n");
printf("scegli: ");
scanf("%d",&risp);
}while ((risp<1) || (risp >2));
if (risp == 2)
{ printf("nome file di ingresso: ");
scanf("%s",nome); }
else
{ printf("nome file dove vuoi memorizzare la popolazione: ");
scanf("%s",nome);
leggiTastiera(nome); }
v = caricaPopolazione(nome, numPop);
limiteDim =(int)floor(log(LONG_MAX)/log(*numPop));
if(limiteDim > *numPop) limiteDim = *numPop;
do{
printf("dammi la numerosita' del campione (deve essere minore di %d): ",limiteDim);
scanf("%d",numCamp);
} while (*numCamp > limiteDim) ;
return v;
}
/*
divide il campo di variazione del vettore dinamico passato in 10 classi e
fornisce la distribuzione del vettore in queste classi
parametri: *v vettore contenente i valori di cui si vuole trovare la distribuzione
int lung: lunghezza del vettore
restituisce un vettore di interi contenente la distribuzione
*/
int * distribuzione(double *v, int lung)
{
int NCLAS = 10; //numero di calssi
int i, j;
int *dist;
if (v==NULL) return NULL;
//campo di variazione MIN e MAX
//minimo
double min = v[0];
for(i=1; i<lung; i++) if(v[i] < min) min = v[i];
//massimo
double max = v[0];
for(i=1; i<lung; i++) if(v[i] > max) max = v[i];
dist = (int*)malloc(sizeof(int)*NCLAS);
for(j=0;j<NCLAS;j++) dist[j] = 0;
//creo la distribuzione
for (i = 0; i<lung; i++) {
for (j = 0; j<NCLAS; j++) {
if ((v[i] >= (min + (max - min)/NCLAS * j)) &&
(v[i] < (min + (max - min)/NCLAS * (j+1))))
dist[j] = dist[j] + 1;
}
if (v[i] == max) dist[NCLAS-1] = dist[NCLAS-1] + 1;
}
return dist;
}
/*
prima ordina gli elementi della popolazione trattata poi calcola la mediana
campionaria di questi
paramentri *v vettore che contiene tutti gli elementi della popolazione
numElem numerosità degli elementi
restituisce il valore della mediana campionaria trovato
*/
double ValAtteso(double *v, int numElem)
{
double somma=0;
double media;
int i;
for (i=0; i<numElem;i++)
{
somma=somma+v[i];
}
media=somma/numElem;
return media;
}
double Varianza(double *v, int numElem)
{
int i;
double varianza;
double scarto;
double somma=0;
double media=ValAtteso(v, numElem);
for(i=0;i<numElem;i++)
{
scarto=(v[i]-media)*(v[i]-media);
somma=somma+scarto;
}
varianza=somma/numElem;
return varianza;
}
/*
genera lo spazio campionario con riposizione di una popolazione finita di
numerosità numPop mediante campioni di numerosità dimSpCa e li scrive su
file calcolando la mediana campionaria del singolo campione.
In fondo al file riporta la media e la varianza dello stimatore e il valore
minimo e massimo assunto dalla mediana campionaria
La funzione ha quattro paramentri:
FILE *fo: puntatore al file su cui scrivere i risultati
int numPop: numerosità popolazione
int dimSpa: numerosità campione
double *pop: vettore della popolazione
Non restituisce niente,scrive direttamente su file
*/
void generaSpazio(FILE *fo, int numPop, int dimSpCa, double *pop)
{ int i, j, *campione;
double *cp; //campione con i relativi valori della popolazione
double *vC; //vettore per la mediana campionaria di ogni campione
long numCamp; //numero di campioni
campione = (int *)malloc(sizeof(int)*dimSpCa);
for(i=0; i<dimSpCa; i++) campione[i] = 1;
//inizializzo primo campione con tutti 1
numCamp=numPop;
for(i=0;i<dimSpCa-1;i++) numCamp= numPop*numCamp;
vC = (double *)malloc(sizeof(double)*numCamp);
fprintf(fo,"\n\nSpazio campionario dei campioni di numerosità %d",dimSpCa);
fprintf(fo," con campionamento casuale semplice.");
fprintf(fo,"\n\nLa popolazione di riferimento ha numerosità: %d\n",numPop);
fprintf(fo,"\n Ci sono %d possibili campioni\n\n",numCamp);
/*le intestazioni*/
fprintf(fo, "\n n:\t");
fprintf(fo,"Campione:\t\t");
fprintf(fo,"Media campionaria:\n\n");
for(j=0; j<numCamp; j++)
{ /* I campioni vengono scritti per riga, il primo numero è l'indice del
campione, gli altri sono i valori che costituiscono il campione.*/
fprintf(fo," %d\t{",j+1);/*indice*/
/*scrittura del campione su una riga*/
for(i=0;i<dimSpCa-1;i++)
fprintf(fo,"%4.2f,",pop[campione[i]-1]);
fprintf(fo,"%4.2f}\t\t",pop[campione[i]-1]);
//scrittura dell'ultimo elemento del campione
cp = (double *)malloc(sizeof(double)*dimSpCa);
for(i=0; i<dimSpCa; i++) cp[i] = pop[campione[i] - 1];
//calcolo e scrittura della media campionaria del singolo campione
double media = 0.0;
for(i=0;i<dimSpCa;i++) media = media + cp[i];
media = media / dimSpCa;
vC[j] =media;
fprintf(fo,"%f\n",media);
free(cp);
//preparazione prossimo campione
campione[dimSpCa-1] = campione[dimSpCa-1]+1;
//incremento di 1 ultimo elemento
for(i=dimSpCa-1; i>0; i--)
if(campione[i] > numPop)
{ campione[i] = 1;
campione[i-1] = campione[i-1] + 1;}
}
fprintf(fo, "\n\n");
//minimo
double min = vC[0];
for(i=1; i<numCamp; i++) if(vC[i] < min) min = vC[i];
fprintf(fo, "Il valore minimo assunto dalla media è %4.4f\n", min);
//massimo
double max = vC[0];
for(i=1; i<numCamp; i++) if(vC[i] > max) max = vC[i];
fprintf(fo, "Il valore massimo assunto dalla media è %4.4f\n", max);
//valore atteso reale
fprintf(fo, "Il valore atteso della media campionaria è %4.4f\n", ValAtteso(vC,numCamp));
//valore atteso stimato
fprintf(fo, "La stima del valore atteso della media campionaria è %4.4f\n", ValAtteso(pop,numPop));
//varianza reale dello stimatore
fprintf(fo, "La varianza della media campionaria è %4.4f\n", Varianza(vC,numCamp));
//varianza stimata dello stimatore
fprintf(fo, "La stima della varianza della media campionaria è %4.4f\n", (Varianza(pop,numPop)/numPop));
//varianza parametro della popolazione
fprintf(fo, "La varianza della popolazione è %4.4f\n", Varianza(pop,numPop));
//ordino i valori della mediaCampionaria
double *vCord = (double *)malloc(sizeof(double)*numCamp);
vCord = MergeSort(vC, numCamp-1);
int m = 1;
fprintf(fo, "\nVALORI ORDINATI DELLA MEDIA\n");
for(i=0;i<numCamp;i++) { if(vCord[i]==vCord[i+1]) m=m+1;
else {fprintf(fo, "%4.4f %d volte\n",vCord[i],m);
m=1;}
}
//creazione della distribuzione
int *distrib = ( int*)malloc(sizeof(int)*10);
distrib = distribuzione(vCord, numCamp);
//scrivo su file la distribuzione
fprintf(fo, "\nDISTRIBUZIONE IN 10 CLASSI:\n\n");
for (j = 0; j<10; j++)
{fprintf(fo, "%4.4f - %4.4f:\t%d\n",(min + (max - min)/10 * j),
(min + (max - min)/10 * (j+1)), distrib[j]);
}
fprintf(fo,"\nN.B tutti gli intervalli includono l'estremo inferiore ed escludono\n");
fprintf(fo," l'estremo superiore tranne l'ultimo intervallo in cui è compreso\n");
//libero la memoria
free(distrib);
free(vCord);
free(vC);
free(campione);
}
int main()
{
double *popol;
int numCamp, numPop;
FILE *fU;
char nomeFile[DIMNF];
popol = caricaParametri(&numCamp, &numPop);
printf("dammi il nome del file di uscita: ");
scanf("%s",nomeFile);
fU = apriFile(nomeFile);
generaSpazio(fU, numPop, numCamp, popol);
fclose(fU);
system("PAUSE");
return(0);
}