View Full Version : [Java] Cognome in codice fiscale,dove sbaglio?
Ciao a tutti!
E' da un paio d'ore, che sto sbattendo la testa su questa porzione di codice
protected String estraiConsonanti(String cognome){
do{
for (int i=0;i<cognome.length();i++){
consExt=cognome.charAt(i);
if(consExt!='A'&&consExt!='E'&&consExt!='I'&&consExt!='O'&&consExt!='U'){
consonantiEstratte=consonantiEstratte+consExt;
if(consonantiEstratte.length()==3){
continua=false;
}
}
}
}while(continua);
return consonantiEstratte;
}
In pratica, con il for scorre tutta la parola (lettera per lettera) contenuta in temp (di tipo String, mettiamo il caso che sia il cognome ="Allegato") passata come parametro.
Nella condizione in cui la lunghezza di temp è uguale a 3, dovrebbe modificare la condizione del do-while e pertanto interrompere l'esecuzione delle istruzioni contenute nel do-while.
Come posso risolvere? A me pare fatto bene, ma evidentemente non è così :)
Grazie mille!
protected String estraiConsonanti(String cognome){
do{
for (int i=0;i<cognome.length();i++){
consExt=cognome.charAt(i);
if(consExt!='A'&&consExt!='E'&&consExt!='I'&&consExt!='O'&&consExt!='U'){
consonantiEstratte=consonantiEstratte+consExt;
if(consonantiEstratte.length()==3){
continua=false;
}
}
}
}while(continua);
return consonantiEstratte;
}
Ad occhio vedo un problemino qui: (Ricorda che 'A' =/= 'a' !)if(consExt!='A'&&consExt!='E'&&consExt!='I'&&consExt!='O'&&consExt!='U'&&consExt!='a'&&consExt!='e'&&consExt!='i'&&consExt!='o'&&consExt!='u')
E poi i cicli sono un po' incasinati...
for(int i = 0; i < cognome.length(); i++) {
if(cognome.charAt(i) != 'A' && /* . . . . */)
consonantiEstratte += cognome.charAt(i);
if(consonantiEstratte.length() == 3)
break;
}
Oppure, sacrificando un po' di leggibilitàfor(int i = 0; i < cognome.length() && consonantiEstratte.length() < 3; i++)
if(cognome.charAt(i) != 'A' && /* . . . . */)
consonantiEstratte += cognome.charAt(i);
p.s. forse ho scritto qualche castroneria, vuoi per l'ora, vuoi perchè non ricordo bene bene la sintassi del java. Nel caso, chiedo perdono :D
Ti ringrazio infinitamente per avermi risposto! Soprattutto a quell'orario... Per quanto riguarda:
Ad occhio vedo un problemino qui: (Ricorda che 'A' =/= 'a' !)
if(consExt!='A'&&consExt!='E'&&consExt!='I'&&consExt!='O'&&consExt!='U'&&consExt!='a'&&consExt!='e'&&consExt!='i'&&consExt!='o'&&consExt!='u')
In un altro metodo viene trasformato con un toUpperCase(); , quindi direi che vada bene.
Ora sistemo come mi hai detto te. Ti faccio sapere.
Grazie mille ancora! :D
Ho risolto così:
protected String estraiConsonanti(String cognome){
for (int i=0;i<cognome.length();i++){
consExt=cognome.charAt(i);
if(consExt!='A'&&consExt!='E'&&consExt!='I'&&consExt!='O'&&consExt!='U'){
consonantiEstratte=consonantiEstratte+consExt;
if(consonantiEstratte.length()==3){
i=cognome.length()+1;
}
}
}
return consonantiEstratte;
}
Nel caso in cui le consonanti estratte sono 3, allora i assume una lunghezza più grande di 1 rispetto alla "lunghezza" del cognome. Questa condizione è sufficiente a rendere falsa la condizione nel for, è così si interrompe restituendomi solo le 3 consonanti cercate.
Nel caso in cui le consonanti estratte sono 3, allora i assume una lunghezza più grande di 1 rispetto alla "lunghezza" del cognome. Questa condizione è sufficiente a rendere falsa la condizione nel for, è così si interrompe restituendomi solo le 3 consonanti cercate.
Se proprio vuoi fare così, io renderei il codice più leggibile ed elegante conif(consonantiEstratte.length()==3)
break;
Se proprio vuoi fare così, io renderei il codice più leggibile ed elegante conif(consonantiEstratte.length()==3)
break;
Funzioni a meraviglia! Non sapevo si potesse usare il break, dentro all'if :eek:
Grazie mille per la risposta e buon Appetito! :D
Funzioni a meraviglia! Non sapevo si potesse usare il break, dentro all'if :eek:
Grazie mille per la risposta e buon Appetito! :D
Glad I could help! :D
p.s. è pericoloso augurarmi buon appetito: per "contorno" ho mangiato 1kg di funghi :asd:
IO devo ancora mangiare... :cry: Ho una fame pazzesca !! :asd:
jappilas
08-01-2011, 16:36
Nel caso in cui le consonanti estratte sono 3, allora i assume una lunghezza più grande di 1 rispetto alla "lunghezza" del cognome. Questa condizione è sufficiente a rendere falsa la condizione nel for, è così si interrompe restituendomi solo le 3 consonanti cercate.Funzioni a meraviglia! Non sapevo si potesse usare il break, dentro all'if :doh:
mi spiace dirtelo, ma nel tuo codice hai commesso svariati errori , alcuni contingenti, altri concettuali
- la tua funzione modifica e ritorna un oggetto stringa non definito localmente - ma se si suppone che consonantiEstratte sia un attributo della classe, non ha senso ritornarlo (siccome lo stai già modificando, eventuali altri metodi di classe ne vedono il nuovo valore)
- un if produce una diramazione dipendente da valori di stato o di input che complica il programma nonchè il suo diagramma di flusso (*), quindi si usa per condizioni note solo a runtime ma non a priori, e si evita il più possibile per controlli impliciti - tu lo usi (complicandoti le cose e rendendo meno chiaro il codice - e meno male che è un caso semplice) per verificare a runtime una condizione che in realtà già conosci: per il codice fiscale si devono prendere esattamente 3 lettere per il nome (e 3 per il cognome), quindi il loop di estrazione va fatto non sulla lunghezza della stringa - e senza uscirne con un break - ma semplicemente da 1 a 3
- e d' altra parte per nomi / cognomi brevi o comunque con poche consonanti mi risulta si usino anche le vocali (tu invece non gestisci tale caso, altro errore) ...
considera "Aldo -> LDA": la prima lettera è una vocale, la scarti e passi alla seconda; la seconda è una consonante, la prendi e passi alla terza; la terza è di nuovo una consonante, la prendi e passi alla quarta; la quarta è una vocale, la scarti e passi alla quinta - ma la quinta non esiste quindi devi tornare alla prima, e considerare le vocali invece delle consonanti; ora, la prima è una vocale, la prendi e hai finito
un algoritmo generico dovrebbe poter essere implementato usando l' indice riferito alla stringa di ingresso, incrementato e poi "riavvolto" una volta finite le consonanti, e una flag (oppure l' indice sempre incrementato, usato come i%cognome.length(), e un check i>cognome.length() al posto della flag, ma è meno leggibile)
* azzarderei un altro suggerimento: quando scrivi del codice, prova a immaginare che qualcuno arrivi e ti chieda di mappare tutti i possibili stati e transizioni da cui il tuo programma è costituito, e di dimostrargli formalmente che tutti gli stati vengano correttamente attraversati in base alle condizioni di lavoro - quasi certamente inizierai a scrivere codice di qualità migliore in cui capirai da solo cosa non va, perchè tu per primo vorrai semplificare al massimo ... ;)
- un if produce una diramazione dipendente da valori di stato o di input che complica il programma nonchè il suo diagramma di flusso (**), quindi
si usa per condizioni note solo a runtime ma non a priori, e si evita il più possibile per controlli impliciti - tu lo usi (complicandoti le cose e rendendo meno chiaro il codice - e meno male che è un caso semplice) per verificare a runtime una condizione che in realtà già conosci
Forse è meglio uno switch?
- e d' altra parte per nomi / cognomi brevi o comunque con poche consonanti mi risulta si usino anche le vocali (tu invece non gestisci tale caso, altro errore) ... considera "Aldo -> LDA":
la prima lettera è una vocale, la scarti e passi alla seconda
la seconda è una consonante, la prendi e passi alla terza
la terza è di nuovo una consonante, la prendi e passi alla quarta
la quarta è una vocale, la scarti e passi alla quinta - ma la quinta non esiste quindi devi tornare alla prima, e considerare le vocali invece delle consonanti
ora, la prima è una vocale, la prendi e hai finito
un algoritmo generico dovrebbe poter essere implementato usando l' indice riferito alla stringa di ingresso, incrementato e poi "riavvolto" una volta finite le consonanti, e una flag (oppure l' indice sempre incrementato, usato come i%cognome.length(), e un check i>cognome.length() al posto della flag, ma è meno leggibile)
Questa parte di codice che ho scritto sul forum, è solo una parte di codice della classe che mi genera il cognome. I cognomi brevi e quelli con meno con meno di 3 consonanti, vengono gestiti da un'altra parte :D
Grazie per i consigli jappilas !
jappilas
08-01-2011, 18:08
io avrei fatto un semplice loop
for (int i=0; i<3; i++)
{
codiceParziale += estraiProssimaConsonante(cognome);
} esterno, piu' una helper function che esamini il cognome lettera per lettera o che ritorni la successiva consonante, ad esempio (riciclando il controllo originale)
private char estraiProssimaConsonante(String cognome)
{
char lettera;
do
{
lettera = cognome.charAt(indice);
indice++;
}
while (lettera =='A' || lettera == 'E' || lettera =='I' || lettera =='O' || lettera =='U');
return lettera;
}:O
questo approccio anche se un po' verboso, ha in realta' il vantaggio di rendere più gestibile il codice, spezzattandolo in "blocchi di complessità" individuali , e sopratutto di renderlo maggiormente testabile (se io volessi controllare il comportamento del mio programma tramite testcase di Junit in questo modo potrei esaminare sia il ciclo esterno sia le funzioni di estrazione - e l' eventuale gestione dei cognomi corti con ricerca delle vocali, essere aggiunta in secondo tempo partendo da codice scheletro già funzionante, aggiungendo una helper function e poco altro - nell' altro modo, no...
Grazie mille per i consigli jappilas! Magari, se riesco pechè non ho molto tempo,provo a darci un'occhitina applicando i tuoi suggerimenti.
Grazie ancora e buona serata! :D
inb4IndexOutOfBoundsException
jappilas
08-01-2011, 21:49
di nulla a presto ;)
inb4IndexOutOfBoundsExceptionmi sembrava chiaro che quel codice fosse solo una "traccia" non da usare così com'è, ma necessitasse comunque di accorgimenti a cui accennavo al post 9 ... ;)
ammetto di non aver letto nient'altro che il post 11 :asd:
vBulletin® v3.6.4, Copyright ©2000-2026, Jelsoft Enterprises Ltd.