[C](Risolto)Migliorare algoritmo per "codificazione"

di il
9 risposte

[C](Risolto)Migliorare algoritmo per "codificazione"

Non sapevo come rendere l'idea nel titolo, comunque ho realizzato un algoritmo che "traduce" una frase in farfallese, una stupida pseudolingua con cui si giocava alle elementari e che consisteva semplicemente nel raddoppiare le vocali delle parole con la "f". Esempi:
a --> afa
e--->efe
ecc. quindi alcune parole sarebbero:
marmellata --> m AFA rm EFE ll AFA t AFA --> mafarmefellafatafa
casa --> c AFA s AFA --> cafasafa

Una stupidata, ma era per impratichirmi un po'.
Ho scritto l'algoritmo, ma andrebbe decisamente migliorato, poichè si che funziona, ma funziona di merda..... intanto copio il codice.

#include <stdio.h>
#include <string.h>

int main (int argc, const char * argv[]) {
	char s1[100];
	char s2[100];
	int v_inserite =0;
	int slittamento;
	int i, lenght;
	
	printf("Questo algoritmo codifica nella segreta lingua del Farfallino."
		   "Per semplicità scrivi tutto in minuscolo.\n"
		   "Inserisci la frase da criptare\n");
	gets(s1); // Per ora non conosco funzioni migliori di gets che prendano anche gli spazi. Lo so che è una merda.
	
	lenght = strlen(s1);
	printf("\nHai inserito: %s\n", s1);
	printf("Lunghezza: %d\n", lenght);
	
	// Sostituisce le varie vocali tenedo conto dello slittamento di indice nel rapporto trai due vettori dato le "f" inserite in più
	for (i=0; i<lenght; i++){
		switch (s1[i]) {
	case 'a':
		slittamento = v_inserite * 2;
		s2[i+slittamento] = 'a';
		s2[1+i+slittamento] = 'f';
		s2[2+i+slittamento] = 'a';
		v_inserite ++;
		break;
	case 'e':
		slittamento = v_inserite * 2;
		s2[i+slittamento] = 'e';
		s2[1+i+slittamento] = 'f';
		s2[2+i+slittamento] = 'e';
		v_inserite ++;
		break;
	case 'i':
		slittamento = v_inserite * 2;
		s2[i+slittamento] = 'i';
		s2[1+i+slittamento] = 'f';
		s2[2+i+slittamento] = 'i';
		v_inserite ++;
		break;
	case 'o':
		slittamento = v_inserite * 2;
		s2[i+slittamento] = 'o';
		s2[1+i+slittamento] = 'f';
		s2[2+i+slittamento] = 'o';
		v_inserite ++;
		break;
	case 'u':
		slittamento = v_inserite * 2;
		s2[i+slittamento] = 'u';
		s2[1+i+slittamento] = 'f';
		s2[2+i+slittamento] = 'u';
		v_inserite ++;
		break;
	default:
		slittamento = v_inserite * 2;
		s2[i+slittamento] = s1[i];
		break;
	}
	}
	
	printf("In Farfallese si pronuncia:\n"
		   "%s", s2);
	
	// Stampo i valori delle variabili per tenere d'occhio il processo
	printf("\nSlittamento: %d", slittamento);
	printf("\nVocali: %d", v_inserite);
	
	return 0;	

}


Ora prescindendo l'ottimizzazione del codice, che sicuramente può essere scritto meglio per risparmiare memoria ( i 100 caratteri massimi dei vettori ad esempio) e anche codice (tipo quel mega switch forse si riesce a ottimizzare), vorrei che prima funzionasse correttamente.
Se inserisco alcune parole va, altre volte invece avanzano nella stringa delle celle che stampa ma che non sono state regolate, non so perchè avanzino ma risultato stampa un paio di numeri a caso.
Esempio:
ceramica --> ceferafamificafa8\367\377\277r\340\217
però su altre funziona tipo:
finestra -->fifinefestrafa.

Se non erro è perchè stampa troppe celle right?
Qualcuno può darmi una mano a venirne a capo?

9 Risposte

  • Re: [C](Risolto)Migliorare algoritmo per "codificazione"

    Devi capire come funzionano le stringhe in C ovvero esseterminano col carattere '\0'
    Se tu sovrascrivi l'ultima cella devi dire tu dove termina la stringa. Se non lo fai il printf va avanti finche non trova un terminatore '\0'
    Ecco perche a volte va e a volte no. Se invece ti degni di azzerrare l'array prima di acquisire la stringa non avrai di questi problemi. Ovviamente l'algo si puo scrivere meglio. se vedi per ogni case tu fai le stesse procedure il che mi fa pensare all'uso di una funzione.
  • Re: [C](Risolto)Migliorare algoritmo per "codificazione"

    S2 non ha il carattere terminatore di stringa '\0'

    ops... ritardo
  • Re: [C](Risolto)Migliorare algoritmo per "codificazione"

    Ho provveduto con la semplice correzione, impostando manualmente il carattere finale '\0' con
    s2[2+i+slittamento] = '\0';
    Ed inoltre ho implementato una funzione per rendere il codice più pulito e meno ridondante. Ma perchè le funzioni si dichiarano prima del main, si invocano nel main ma si implementano dopo? So che non cambia nulla implementarle subito, ma allora perchè non fanno tutti così? (Perlomeno sulle guide che ho trovato)
    Comunque solo un ultimo problema prima di considerare compiuto il programino: non c'è un modo per renderlo più efficiente dal punto di vista della memoria, senza dover dichiarare 2 vettori da 100 elementi che bloccano 200 celle di memoria? Sfruttando magari malloc per bloccare solo la quantità di celle strettamente necessaria. Prescindendo il fatto che con tutti i giga di RAM di oggi non fa certo la differenza, come "stile" di programmazione sarebbe consigliato o ce se ne frega? E se si come farei, visto che per malloc dovrei sapere prima quanti caratteri verranno inseriti, e certo mica posso chiederli all'utente, mica può contare i caratteri prima di scrivere giù la frase, sarebbe ridicolo.
    Grazie mille comunque per le dritte
  • Re: [C](Risolto)Migliorare algoritmo per "codificazione"

    Ma perchè le funzioni si dichiarano prima del main, si invocano nel main ma si implementano dopo? So che non cambia nulla implementarle subito, ma allora perchè non fanno tutti così? (Perlomeno sulle guide che ho trovato)
    Perche' nei sorgenti si includono le definizioni in testa, in un header apposito che ha un estensione .h, che contiene (tra le altre cose) i prototypes delle funzioni da richiamare. Questo consente di utilizzare le funzioni, includendo l'header, in altri sorgenti mentre Il linker provvedera' ad inserirle nel contesto.
    Qualora ci fossero funzioni uitlizzate localmente, all'interno dello stesso codice sorgente, si puo' mettere la funzione prima della chiamata omettendo la definizione. Ecco perche' nei piccoli programmini di esempio trovi prima le funzioni e poi per ultimo il main.
    Comunque solo un ultimo problema prima di considerare compiuto il programino: non c'è un modo per renderlo più efficiente dal punto di vista della memoria, senza dover dichiarare 2 vettori da 100 elementi che bloccano 200 celle di memoria? Sfruttando magari malloc per bloccare solo la quantità di celle strettamente necessaria. Prescindendo il fatto che con tutti i giga di RAM di oggi non fa certo la differenza, come "stile" di programmazione sarebbe consigliato o ce se ne frega? E se si come farei, visto che per malloc dovrei sapere prima quanti caratteri verranno inseriti, e certo mica posso chiederli all'utente, mica può contare i caratteri prima di scrivere giù la frase, sarebbe ridicolo.
    in C lo puoi fare con la funzione realloc che devi richiamare quando il buffer cresce oltre la dimensione stabilita.
  • Re: [C](Risolto)Migliorare algoritmo per "codificazione"

    Se usi il C++ puoi tranquillamente utilizzare le stringhe, anziché gli scomodi vettori.
    ad esempio:
    string a;
    getline(cin, a);
    for (int i=0; i<=a.lenght; i+=1)
         {if ((int) a[i] == (qui metti il codice ascii della "a" || (int) a[i] == (codice della "e") ||ecc
           cout << (char) a[i] << "f" << (char) a[i];
    else
           cout << (char) a[i]; 
    Questo è solo un esempio, da migliorare tantissimo. Ad esempio, oltre ad inserire qualche linea di testo del tipo "digita stringa" ecc, potresti inserire un comando dopo il ciclo for che ripeta la linea di testo (come goto etichetta). se hai dubbi, o se il mio codice è poco comprensibile (molto probabile) non esitare a chiedere, risponderò il prima possibile.
  • Re: [C](Risolto)Migliorare algoritmo per "codificazione"

    
    ...
         {if ((int) a[i] == (qui metti il codice ascii della "a" || (int) a[i] == (codice della "e") ||ecc
           cout << (char) a[i] << "f" << (char) a[i];
    else
           cout << (char) a[i]; 
    ...
    
    Ciao Monkey D. Patie, perché ripeti?
    
    ...
           cout << (char) a[i]; 
         {if ((int) a[i] == (qui metti il codice ascii della "a" || (int) a[i] == (codice della "e") ||ecc
           cout << "f" << (char) a[i];
    ...
    
  • Re: [C](Risolto)Migliorare algoritmo per "codificazione"

    Intendi perché metto due volte
     (char) a[i] 
    nel comando cout relativo al caso in cui a = vocale? oppure intendi le condizioni del "if" ?
  • Re: [C](Risolto)Migliorare algoritmo per "codificazione"

    Si, nel senso della semplificazione, togliere parti identiche nelle condizionioni if/else.
  • Re: [C](Risolto)Migliorare algoritmo per "codificazione"

    Si, è da ottimizzare
Devi accedere o registrarti per scrivere nel forum
9 risposte