Cerca nel blog

Pubblicità

banner-125x125 banner-125x125 banner-125x125 banner-125x125

Feed RSS e Newsletter

Puoi seguire il mio blog abbonandoti al feed RSS, se non sai cos'è un feed RSS prova a guardare questo video... Spiega tutto!

Icona Feed RSS

Twitter

PayPal

Se ti piace questo blog puoi pensare ad una donazione.

Tutti i fondi ricevuti saranno utilizzati per il mio sollazzo personale. :-)

Ultimi commenti...

Teo: Napolux ha scritto: Però se lo scrivi sul contratto che il cliente firma immagino sia legale Non so quanti...

Napolux: Teo ha scritto: In pratica devi inserire il codice che ti propone nelle pagine web che generi e se non ti...

Teo: In pratica devi inserire il codice che ti propone nelle pagine web che generi e se non ti paga lo blocchi?...

Teo: Occhio gente, secondo me arriva dritta dritta una denuncia ad usarlo… Ma, in pratica, come agisce?? :razz:

Teo: Sbronzo di Riace ha scritto: io dico che bisognerebbe fare un decreto interpretativo sulla questione e già che...

Da numeri a lettere in PHP

lunedì 1 dicembre 2008
1 Star2 Stars3 Stars4 Stars5 Stars (1 voti, media: 5,00)
Loading ... Loading ...

Ogni bravo professore di informatica delle scuole superiori dovrebbe proporre ai propri studenti questo quesito: "Scrivi una funzione che traduce un qualsiasi numero intero da 0 a 999.999.999 in lettere".

A me è successo e ricordo ancora con piacere il lunghissimo programma Pascal che avevo realizzato e che funzionava solo in parte. Dopo "qualche" anno ho trovato dieci minuti per riprendere in mano quel progettino ed è venuto meglio di quanto mi aspettassi.

Spero possa essere di ispirazione (e non solo "da copiare") anche per chi magari ha 15 anni e si ritrova ancora a dover affrontare il mio stesso problema.

function traslitterazione($numero)
{
	$unita     		= array("","uno","due","tre","quattro","cinque","sei","sette","otto","nove");
	$decina1 		= array("dieci","undici","dodici","tredici","quattordici","quindici","sedici","diciassette","diciotto","diciannove");
	$decine	   		= array("","dieci","venti","trenta","quaranta","cinquanta","sessanta","settanta","ottanta","novanta");
	$decineTroncate = array("","","vent","trent","quarant","cinquant","sessant","settant","ottant","novant");
	$centinaia 		= array("","cento","duecento","trecento","quattrocento","cinquecento","seicento","settecento","ottocento","novecento");

	// Inizializzo variabile contenente il risultato
	$risultato = "";

	// Faccio padding a 9 cifre
	$stringa = str_pad($numero, 9, "0", STR_PAD_LEFT);

	// Per ogni gruppo di tre cifre faccio il conto
	for($i=0;$i<9;$i=$i+3)
	{
		// Uso una variabile temporanea
		$tmp = "";

		// Centinaia
		$tmp .= $centinaia[$stringa[$i]];		

		// Decine da 2 a 9
		if($stringa[$i+1] != "1")
		{
			if($stringa[$i+2] == "1" || $stringa[$i+2] == "8")
				$tmp = $tmp . $decineTroncate[$stringa[$i+1]];
			else
				$tmp = $tmp . $decine[$stringa[$i+1]];		

			$tmp = $tmp . $unita[$stringa[$i+2]];
		}
		else // Undici, dodici, tredici, ecc...
		{
			$tmp .= $decina1[$stringa[$i+2]];
		}

		// Aggiungo suffissi quando necessario
		if($tmp != "" && $i==0)
					$tmp .= "milioni";

		if($tmp != "" && $i==3)
					$tmp .= "mila";

		// Aggiungo a risultato finale
		$risultato .= $tmp;

		// Caso speciale "mille" / "un milione" -> RISOLVE BUG "unmilioneunomilauno"
		if($i == 0 && $stringa[$i] == "0" && $stringa[$i+1] == "0")
			$risultato = str_replace("unomilioni","unmilione",$risultato);
		if($i == 3 && $stringa[$i] == "0" && $stringa[$i+1] == "0")
			$risultato = str_replace("unomila","mille",$risultato);
	}

	// ZERO!
	if($risultato == "")
		return "zero";
	else
		return	$risultato;
}

// Restituisce "tredicimilacinquecentoquarantasei"
echo traslitterazione(13546);

Potete vedere un esempio funzionante della funzione qui sopra a questo indirizzo.

Ho testato a lungo tutto e la funzione si è rivelata sempre corretta. Se trovate un numero che non viene traslitterato correttamente lasciate un commento, segnalando il numero che crea il problema.

Il codice non è complesso, ecco cosa fa:

  • Vengono creati quattro array contenenti le stringhe
  • Ricevuto in input il numero fa il padding a 9 cifre riempiendo con 0 i posti mancanti
  • Per ogni gruppo di tre cifre viene calcolata la stringa corrispondente, tenendo conto di casi speciali quali undici, dodici, tredici... E troncamenti come ventuno, trentotto, ecc...
  • Viene aggiunto il suffisso decimale (milioni, migliaia)
  • Vengono trasformati casi speciali come zero, unmilione, mille
Volendo cercare di essere il più corretto possibile ho anche aperto una discussione in un newsgroup Usenet che si occupa della lingua italiana. Le risposte ricevute sono state molto interessanti.

Che ne dite? Avete soluzioni migliori sottomano? :)

UPDATE!
Risolto bug segnalato nei commenti (errata traslitterazione del numero "unmilioneunomilauno" e similari). Grazie per il feedback!

Questo articolo è stato pubblicato lunedì, 1 dicembre 2008 alle ore 09:10 Se non vuoi perdere nemmeno un articolo del mio blog abbonati al feed RSS. Se non sai cos'è un feed RSS puoi guardare questo video, spiega tutto!

In alternativa puoi abbonarti alla newsletter, riceverai un'email ogni volta che verrà pubblicato un nuovo post. Il tuo indirizzo email sarà gestito da Feedburner.

  

9 Commenti a “Da numeri a lettere in PHP”

  1. Matteo scrive:

    Più che altro, il succitato professore dovrebbe saperlo fare :) Comunque ne ricordo uno altrettanto divertente, che ci fecero fare al primo anno di università: convertire un numero in numeri romani (e viceversa). La soluzione, però, è fuori dalla mia memoria.

  2. Lorenzo scrive:

    L’ avevo fatto anche io qualche tempo fa ;)
    Anche quello dei numeri romani, solo da intero a romano però, non viceversa.

    Dovrò andare a ripescarli chissà dove..

    Napolux: Natale all’ insegna della programmazione ? :p

  3. Piplos scrive:

    Hm ottimo. Mi hai dato lo spunto per scervellarmi con java. Sai, sono al primo anno di informatica e una cosa del genere in java DEVO saperla fare :)

    Fin quando non avrò finito non sbircierò nemmeno il tuo codice. :P

  4. Piplos’ blog » Convertire un numero in binario in Java scrive:

    [...] di codice è stato “archiviato”, posso dedicarmi a scrivere un altro programma di ben altro calibro. Staremo a [...]

  5. Cosa scriverai oggi? | Napolux.com scrive:

    [...] la tombola di famiglia? Salta fuori un post sulla tombola. Mi ricordo dei tempi delle superiori? Ecco un tutorial su una “verifica” di quei tempi. Senza dimenticare tutto il [...]

  6. p3go83 scrive:

    Bella lì! Mi hai evitato almeno un’ora di sbattimento! Tnx

  7. Diegobeds scrive:

    Ciao,
    non per essere pignolo, ma la correzione dei casi speciali
    # // Caso speciale: mille, un milione
    # $risultato = preg_replace(“/^unomila/”,”mille”,$risultato);

    non tiene conto del caso “mille” se ci sono cifre nell’ordine dei milioni.
    es. 1001001 => unmilioneunomilauno

    :)

    P.S: giuro che non li ho provati tutti da zero, né che ho analizzato il codice e trovato il bug, mi ha solo detto sfiga al secondo tentativo :)

  8. Napolux scrive:

    @ Diegobeds:
    E’ un bug che mi ha segnalato un altro lettore 2 settimane fa. Nel week-end mi ci metto… Se nel frattempo trovi una soluzione… Postala!

    Ci metto i credits, eh… :P

  9. Napolux scrive:

    @ Diegobeds:
    Bug risolto e post aggiornato!