PDA

Visualizza la versione completa : [C] tempo di esecuzione?


carlogts
27-07-2013, 19:26
Salve a tutti ragazzi ho un problemino, non ho la più pallida idea di come si fa a calcolare il tempo di esecuzione dell'algoritmo seguente (derivata):


#include <stdio.h>
#include <stdlib.h> /* I N F O 23.07.2013 h 10.30 */
#include <string.h>
#include <ctype.h>

#define DIM 32
#define archivio "funzione.dat"
#define archivio2 "derivata.dat"


/* Prototipi delle funzioni */
void presenta();
void acquisisci(char *funzione);
void costruiscifx();
int strpos(char *funzione, char *token);
int ScriviFunz(char fxpref[DIM], char nomefile[]);
void elabora();
int LeggiFunz(char fxpref[DIM], char nomefile[]);
int ScriviDer(char fxder[DIM], char nomefile[]);
int LeggiDer(char fxder[DIM], char nomefile[]);






char radice[1];
int lun,lfx,lfsin,lfdes,lprimofdes;// variabili lunghezza funzione: primitiva,sottoalberosx, sottoalberodx
int indprimarad; // posizione prima radice della funzione
char fxprefissa[DIM]="";
char derivata[DIM]="";
char token[18]={'+','-','*','/','^','1','2','3','4','5','6','7','8','9','s','c', 'x','\0'};// vettore dei token ammessi
char funzione[DIM];

int j; // indice vettore dei token ammessi
int trovato=0; // flag esito ricerca token
char fdes[DIM]=""; // sottoalberodx
char fsin[DIM]=""; // sottoalberosx
char sim[DIM]; // appoggio singolo carattere della funzione
int passo,esiste;

int main(int argc, char *argv[]) {

presenta();
acquisisci(funzione);// acquisizione funzione derivanda
costruiscifx();
elabora();
LeggiDer(derivata, archivio);
printf("\nderivata prima della funzione = %s\n ",derivata);
system("PAUSE");
return 0;
}

void costruiscifx(){

lun=strlen(funzione);lfx=lun;
passo=0;
j=0;//indice dei caratteri ammessi
while (strlen(fxprefissa)<lfx){
while (trovato==0){
lun=strlen(funzione);
strcpy(sim,&token[j]);
lfsin=strpos(funzione,sim);
if(lfsin==-1) // lfsin= posizione della radice
{/* elemento non trovato */ }
else{passo++;
strncpy(radice,sim,1);
trovato=1;
memset(fsin, '\0', sizeof(fsin)); // inizializza la stringa col carattere di terminazione
strncpy(fsin,funzione,lfsin);
lfdes=lun-(lfsin+1);
if (passo==1) {indprimarad=lfsin;lprimofdes=lfdes;}
memset(fdes, '\0', sizeof(fdes)); // inizializza la stringa col carattere di terminazione
strncpy(fdes,&funzione[lfsin+1],lfdes);
strcat(fxprefissa,radice);strcpy(funzione,"");
strcpy(funzione,fsin);strcat(funzione,fdes);
if(lfsin==1)
{
strcat(fxprefissa,fsin);strcpy(funzione,"");
strcpy(funzione,fdes);
}
}
j++;
}
j=0;
trovato=0;
}
printf("\nScrittura su file...\n");
ScriviFunz(fxprefissa, archivio);//il file dati viene scritto
return;
}



void elabora(){

int coseno=1;int seno=1;int ele=0;
int j,coeff,grado,app;
char cc[DIM];//carattere corrente della funzione prefissa
char tri[3];// variabile temporanea per contenere sx o cx
char auxco[3];
char auxgr[3];
char segno[2];
memset(segno, '\0',sizeof(segno));
esiste=LeggiFunz(fxprefissa, archivio);
if (esiste==1){
lun=strlen(fxprefissa);
coeff=1;
memset(cc, '\0', sizeof(cc));
memset(tri, '\0', sizeof(tri));
strncat(segno,&fxprefissa[0],1);
j=0;//indice dei caratteri ammessi
while ((j<lun)&&(coseno!=0)){j++; // cerca la presenza della funzione coseno -
memset(cc, '\0', sizeof(cc));
strncat(cc,&fxprefissa[j],1);
coseno=strcmp(cc,"c");
app=atoi(cc);
if ((app>=1)&&(app<=9)){coeff=coeff*app;grado=0;}
}
j=0;//indice dei caratteri ammessi
while ((j<lun)&&(seno!=0)){j++; // cerca la presenza della funzione seno
memset(cc, '\0', sizeof(cc));
strncat(cc,&fxprefissa[j],1);
seno=strcmp(cc,"s");
}
j=0;//indice dei caratteri ammessi
while ((j<lun)&&(ele==0)){j++; // cerca la presenza della funzione seno
memset(cc, '\0', sizeof(cc));
strncat(cc,&fxprefissa[j],1);
if(strcmp(cc,"^")==0) {ele=j;coeff=atoi(&fxprefissa[ele-1]);grado=atoi(&fxprefissa[ele+2]);coeff=coeff*grado;};
}
memset(derivata, '\0', sizeof(derivata));
if(coseno==0) {//coseno trovato il segno della derivata cambia
strcpy(tri,"sx");
if (strcmp(segno,"-")==0) {strcpy(derivata,"+");}
else {strcpy(derivata,"-");}
}
if(seno==0) {//il segno della derivata non cambia
strcpy(tri,"cx");
strcat(derivata,segno);
}

if(ele!=0) {
if (grado>1){//derivata di termine di grado > 1
grado--;itoa(coeff,auxco,10);itoa(grado,auxgr,10);
strcat(derivata,"*");strcat(derivata,auxco);strcat(derivata,"^x");strcat(derivata,auxgr);strcat(derivata,tri);
}
else
if (grado=1){//derivata di termine di grado = 1
itoa(coeff,auxco,10);
strcat(derivata,auxco);strcat(derivata,tri);
}
}
else { strcat(derivata,tri);} //derivata della costante
ScriviDer(derivata, archivio2);
}
else printf("Impossibile aprire in lettura il file %s\n", archivio);
return;
}


int ScriviFunz(char fxpref[DIM], char nomefile[])
{
FILE *fp;
fp = fopen(nomefile, "w");
if( fp == NULL)
{
printf("Impossibile aprire in scrittura il file %s\n", nomefile);
return 0;
}
fwrite(fxpref,32,1,fp);
return 1;
}

int LeggiFunz(char fxpref[DIM], char nomefile[])

{
FILE *fp;
printf("\nLettura funzione derivanda da file... ");
fp = fopen(archivio, "r");
if( fp == NULL)
{
printf("\nL'archivio non esiste. Impossibile aprire in lettura il file %s\n", fp);
return 0;
}
fread(fxpref,32,1,fp);
return 1;
}

int ScriviDer(char fxder[DIM], char nomefile[])
{
FILE *fp;
fp = fopen(nomefile, "w");
if( fp == NULL)
{
printf("Impossibile aprire in scrittura il file %s\n", nomefile);
return 0;
}
fwrite(fxder,32,1,fp);
return 1;
}

int LeggiDer(char fxder[DIM], char nomefile[])

{
FILE *fp;
printf("\nLettura derivata prima della funzione da file... ");
fp = fopen(nomefile, "r");
if( fp == NULL)
{
printf("\nL'archivio non esiste. Impossibile aprire in lettura il file %s\n", fp);
return 0;
}
fread(fxder,32,1,fp);
return 1;
}


void presenta(){
printf("\n\Inserire la funzione da derivare osservando le seguenti regole:\n");
printf("\nI termini goniometrici ammessi sono:\n");
printf("\n\tdigitare sx = per ottenere: sen(x)");
printf("\n");
printf("\n\tdigitare cx = per ottenere: cos(x)");
printf("\n");
printf("\nI monomi ammessi sono:\n");
printf("\n\tdigitare 3*x^1 per ottenere: 3* x (elevato a 1)");
printf("\n");
printf("\n\tdigitare 4*x^3 per ottenere: 4* x (elevato a 3)\n");
printf("\n\t\tEsempio: 8*x^3-cx \n");
printf("\nDigitare la funzione:");

}
void acquisisci(char *funzione){

fgets(funzione,DIM,stdin);
funzione[strlen(funzione)-1] = 0;
}

int strpos(char *funzione, char *token){
//dichiarazioni
int i,j,n,l;
//inizializzazioni
l=1;
n = strlen(funzione)-l+1;
//calcoli
for(i=0;i<n;i++){
for(j=0;j<l&&token[j]==funzione[i+j];j++);
if(j==l)
return i;// restituisce la posizione del token all'interno della stringa funzione
}
return -1;// restituisce -1 poiché il token corrente non corrisponde ad alcun carattere della funzione
}

Qualcuno sa come calcolarlo?
Grazie in anticipo.

lovesemiramide
27-07-2013, 20:36
Puoi usare alcuni membri di time.h (http://www.cplusplus.com/reference/ctime/).

Questa è la struttura principale:


clock_t timer = clock();
/* codice che vuoi */
timer = ( clock() - timer) / CLOCKS_PER_SEC;

carlogts
27-07-2013, 20:39
in quale parte del programma la devo inserire?

lovesemiramide
27-07-2013, 21:56
Beh, dipende dalla parte che vuoi "cronometrare".

Per esempio se vuoi misurare la durata dell'intero programma puoi fare così:


int main(int argc, char *argv[]) {
clock_t timer = clock();
presenta();
acquisisci(funzione);// acquisizione funzione derivanda
costruiscifx();
elabora();
LeggiDer(derivata, archivio);
printf("\nderivata prima della funzione = %s\n ",derivata);
system("PAUSE");
timer = ( clock() - timer) / CLOCKS_PER_SEC;
return 0;
}

carlogts
27-07-2013, 22:40
grazie mille! mi sei stato veramente d'aiuto! ancora grazie

MItaly
28-07-2013, 01:54
Ti ricordo che:

il codice va specificato tra tag
... , altrimenti perde l'indentazione;
il linguaggio di riferimento va sempre specificato (anche nel titolo, sotto forma di "tag").


Ora correggo io, in futuro imposta correttamente la discussione fin da subito; nel frattempo ti consiglio di dare un'occhiata al regolamento (http://forum.html.it/forum/showthread.php?s=&threadid=973887).
:ciauz:

MItaly
28-07-2013, 01:57
Per inciso, questa riga:


timer = ( clock() - timer) / CLOCKS_PER_SEC;

non è una buona idea, dato che, se come spesso accade, time_t e CLOCKS_PER_SEC sono di tipi interi, viene effettuata una divisione intera, in cui ti perdi tutti i decimali. Per questo motivo, è più opportuno fare una cosa di questo genere:


double t=(clock()-timer + 0.0) / CLOCKS_PER_SEC;

dove la somma di 0.0 forza la conversione a double (o a long double, nel caso clock_t fosse tale) e impone che venga effettuata una divisione "vera"; infine, il risultato viene assegnato ad una variabile di tipo double, in modo da non perdersi i decimali.

Scara95
28-07-2013, 06:56
Poi sarebbe il caso di metterla prima della chiamata a system...
Non credo voglia misurare la sua reattività nel premere invio :D

lovesemiramide
28-07-2013, 10:44
non è una buona idea, dato che, se come spesso accade, time_t e CLOCKS_PER_SEC sono di tipi interi, viene effettuata una divisione intera, in cui ti perdi tutti i decimali. Per questo motivo, è più opportuno fare una cosa di questo genere:

double t=(clock()-timer + 0.0) / CLOCKS_PER_SEC;
Non sapevo di questa "particolarità", grazie per la spiegazione.


Poi sarebbe il caso di metterla prima della chiamata a system...
Non credo voglia misurare la sua reattività nel premere invio :D
Se è per questo non penso voglia misurare neanche la capacità dell'utente di scrivere la funzione...

Heine_cantor
28-07-2013, 18:55
Originariamente inviato da lovesemiramide
Non sapevo di questa "particolarità", grazie per la spiegazione.


Se è per questo non penso voglia misurare neanche la capacità dell'utente di scrivere la funzione...
Se ricordo bene in realtà dovrebbe non tener conto delle funzioni di imput/output quindi va bene così diciamo :D

Loading