PDA

Visualizza la versione completa : [C] ciclo while con interruzione


rosencrruetz
13-01-2015, 11:10
Buongiorno a tutti,
vi posto un codice che ho scritto, fondamentalmente un ciclo while con un'interruzione. Il codice dovrebbe andare ma a mio parere (da principiante) direi che tutt'altro che ottimizzato, non riesco a capire come..
In sostanza, letto un carattere lo si deve confrontare con i caratteri presenti in una tabella.
La tabella fatta cos: tab[26][2], nella prima colonna ci sono i caratteri da fornire in output mentre nella seconda colonna quelli da confrontare con il carattere in input.



i=0;
j=0;
c=getc(f); //leggo carattere da file
if (tab[i][2]==c)
fprintf(f2,"%c", tab[1][1]; //stampa il valore nel file
else
while (tab[i][2]!=c)
{
if(tab[i+1][2]==c) //se hai trovato il valore
{
fprintf(f2,"%c", tab[i+1][1]); //stampa il valore nel file
break; //esci da while
}
i++;
}

Tutto questo codice inserito in un altro ciclo while, quello classico usato per la lettura di un file
Si poteva fare anche con un semplice ciclo for (da 0 a 26, viste le 26 righe della tabella) ma uno spreco di risorse, visto che il match tra input e output univoco...
Spero ci sia un modo migliore per fare il tutto

Grazie

Scara95
13-01-2015, 11:28
Nel tuo codice controlli la stessa condizione 3 volte, in sostanza.
Uno dei modi pi compatti per scriverlo con un while questo (assumendo che tutti i caratteri in input siano presenti nella tabella):

int i = 0;
while(tab[i][2]!=c) ++i;
fputc(tab[i][1], f2);
oppure (senza assumere che tutti i caratteri in input siano presenti nella tabella)

int i = 0;
while((tab[i][2]!=c) && (i<TAB_LENGTH)) ++i;
if(i!=TAB_LENGTH) fputc(tab[i][1], f2);

Tuttavia c' un modo assai pi efficiente, una hashtable.
Nel caso dei caratteri piuttosto semplice in quanto ogni carattere in sostanza un numero e basta trasformare questo numero in un indice per la tua tabella.
Per farlo bisogna per conoscere i caratteri interessati.

rosencrruetz
13-01-2015, 11:37
int i = 0;
while(tab[i][2]!=c) ++i;
fputc(tab[i][1], f2);
Ecco la soluzione ottimizzata che cercavo, grazie. In pratica, finch non trovi il match semplicemente incrementa l'indice di riga, quando lo trova si blocca il while e a quel punto, con quell'indice i stampa su file. Come ho fatto a non pensarci? :D


Tuttavia c' un modo assai pi efficiente, una hashtable.
Nel caso dei caratteri piuttosto semplice in quanto ogni carattere in sostanza un numero e basta trasformare questo numero in un indice per la tua tabella.
Per farlo bisogna per conoscere i caratteri interessati.
Non so cosa sia una hashtable, nel mio caso un abbozzo di algoritmo per decrittografare.
Tab di conversione (prima col:corretto, seconda col: crittografato):
A-H
B-Z
C-K
...
leggi Z allora stampa B ---> leggi K allora stampa C e cos via per tutto il file, carattere per carattere

Scara95
13-01-2015, 12:08
Allora per le tabelle di conversione ti basta fare cos:
#include <stdio.h>

#define LEN ('Z'-'A'+1)
#define BASE 'A'


int main(void) {
char crypt[LEN];
crypt['A'-BASE] = 'H'; //'A'-BASE <=> 0
crypt['B'-BASE] = 'Z'; //'B'-BASE <=> 1
crypt['C'-BASE] = 'K'; //'C'-BASE <=> 2
//...
char decrypt[LEN];
int i;
for(i = 0; i < LEN; ++i)
decrypt[crypt[i]-BASE] = i+BASE;
//...

//decrypt
char c = fgetc(f);
c -= BASE;
if(c >= 0 && c < LEN) fputc(decrypt[c], f);

//crypt
char c = fgetc(f);
c -= BASE;
if(c >= 0 && c < LEN) fputc(crypt[c], f);
return 0;
}

Non ho scritto per intero le assegnazioni e non mi sono preoccupato di aprire un file.

Loading