Pagina 2 di 3

Re: funzione conversione numero in lettere

MessaggioInviato: 18 feb 2023, 23:53
da dadduni
Se devi convertire un numero letto in Italian in un numero forse puoi scrivere una macchina a stati abbastanza complessa ma che occupa meno spazio di una LUT.
per esempio leggi la prima lettera e decidi quale numero puo risultare. Poi leggendo le altre lettere decidi.
Per esempio se leggo C può essere cinque, cinquanta, Cinquecento, cinquantamila ecc... Leggendo le altre lettere e la lunghezza della stringa iniziale puoi avvicinarti sempre di più al risultato finale

Re: funzione conversione numero in lettere

MessaggioInviato: 19 feb 2023, 9:15
da MarcoD
Ringrazio tutti per le osservazioni, ma in particolare ringrazio Foto Utentedjnz per i miglioramenti al mio programma, è proprio quello che desideravo.
Questo è proprio lo scopo del forum, permette di ricevere approcci differenti allo stesso problema e in conclusione a migliorare le proprie conoscenze.
Oggi, purtroppo non ho tempo, nei prossimi giorni provvederò a studiarli e a introdurli. thanks.
O_/

p.s.: anche il suggerimento di Foto Utentedadduni per la funzione inversa è interessante.

Re: funzione conversione numero in lettere

MessaggioInviato: 19 feb 2023, 14:47
da djnz
dadduni ha scritto:Se devi convertire un numero letto in Italian in un numero forse puoi scrivere una macchina a stati abbastanza complessa ma che occupa meno spazio di una LUT.

Oppure strategia bruteforce, a partire dal numero (0..999) generi ciclicamente tutte le stringhe e le confronti con quella da ritrasformare in numero. Prezzo da pagare: il tempo. Ben 66,4 ms per generare tutte le mille stringhe :mrgreen:

Re: funzione conversione numero in lettere

MessaggioInviato: 19 feb 2023, 17:10
da Etemenanki
Perche' mille stringhe ?

Ok, da 0 a 19, servono 19 stringhe, ma poi la cosa si semplifica, per ogni decina solo 2 (esempio "venti" per 20, 22, 23, 24 ,25 ,26, 27, 29, e "vent" per 21 e 28, lo stesso per tutte le altre decine), per le centinaia altre 9 stringhe, per le migliaia altre 9, per le decine di migliaia solo "mila" (da accodare alle precedenti stringhe da "dieci" a "diciannove", e cosi via, poi e' tutta una sessione di cucito (che, ammetto, non e' semplicissima, ma non credo sia impossibile, dato che alcuni sintetizzatori vocali gia lo fanno ;-) ).

Esempio, 14723, "quattordici"+"mila"+"settecento"+"venti"+"tre" ... e cosi via :mrgreen:

Re: funzione conversione numero in lettere

MessaggioInviato: 19 feb 2023, 18:07
da djnz
Etemenanki ha scritto:Perche' mille stringhe ?

Mille stringhe complete (una per ogni numero a partire da 'zero' per arrivare a 'nove'+'cento'+'novant'+'a'+'nove') formate dalla combinazione di 32 sottostringhe base.

Re: funzione conversione numero in lettere

MessaggioInviato: 19 feb 2023, 18:56
da nicsergio
Se ti servisse risparmiare SRAM, visto che su Arduino è poca ed usando array di caratteri la consumi velocemente, le varie stringhe costanti usate per comporre l'output le potresti tenere su memoria Flash e poi usare strcat_P() anziché strcat(), esempio:

Codice: Seleziona tutto
strcat_P(str, PSTR("cento"));

Re: funzione conversione numero in lettere

MessaggioInviato: 19 feb 2023, 21:50
da GioArca67
Pseudocodice, senza alcuna prova...e senza garanzia... gli spazi iniziali contano, %=resto
Giusto un'idea
Codice: Seleziona tutto
primi20num = {"zero","uno", "due",...,"dieci", "undici",...,"diciannove"}
nomedecine={null,null,"vent","trent",...,"novant"}

func converti(num)
  if(num>999)
    return "numero troppo grande"
  if(num<0)
    return "meno"+converti(-num)
  if(num>=100)
    return (num==100)?{}:{primi20num[int(num/100)]}+"cento "+(num%100<>0)?{converti(num%100)}:{}
  if(num>=20)
    decine=int(num/10)
    unita=num-decine*10
    interc=(decine==2)?{"i"}:{"a"}
    return nomedecine[decine]+(unita==1||unita==8)?{}:{interc}+(num%10<>0)?{converti(num%10)}:{}
  return primi20num[num]


La ricorsione puoi toglierla facilmente

Re: funzione conversione numero in lettere

MessaggioInviato: 19 feb 2023, 22:22
da GioArca67
Codice: Seleziona tutto
primi20num = {"zero","uno", "due",...,"dieci", "undici",...,"diciannove"}
nomedecine={null,null,"vent","trent",...,"novant"}

func converti(num)
  if(num>999)
    return "numero troppo grande"

  if(num==0)return primi20num[0]

  ris=""
  if(num<0)
    ris="meno "
    num=-num

  if(num>=100)
    centinaia=int(num/100)
    if(centinaia>1)ris=ris+primi20num[centinaia]
    ris=ris+"cento"
    num=num-centinaia*100
    if(num==0) return ris //era centinaia tonda, es 300

  if(num<20)return ris+primi20num[num]

  decine=int(num/10)
  unita=num-decine*10
  interc=(decine==2)?{"i"}:{"a"}
  ris=ris+nomedecine[decine]
  if(unita<>1&unita<>8)ris=ris+interc
  ris=ris+primi20num[unita]
  return ris

Re: funzione conversione numero in lettere

MessaggioInviato: 19 feb 2023, 22:23
da stefanopc
Mi viene in mente la "voce automatica " che annunciava con difficoltà numero dei treni, la destinazione e il relativo binario alla stazione centrale di Milano (qualche anno fa) .

In ambito telecomunicazioni si trasmettevano ( in alcuni casi ne esistono di ancora in funzione) gli allarmi con un sistema che poteva essere interrogato via telefono.
Alla risposta veniva inviata una successione di impulsi (note) a due frequenze .
Il tono a bassa frequenza indicava no allarme.
Il tono a frequenza più alta indica allarme presente.
Il tutto organizzato in decine con pausa differenziata tra una decina e la successiva.
Al termine il sistema ricomincia da capo emettendo una nota di lunghezza maggiore per avvisare dell'inizio della sequenza.
In questo caso potresti trasmettere a toni le tre cifre una per volta.
Questo sistema non richiede la conoscenza del codice morse e risulta molto facile da decifrare anche con un pessimo rapporto S/N.
Non è la risposta al quesito ma un modo di ovviare al problema.
Ciao

Re: funzione conversione numero in lettere

MessaggioInviato: 20 feb 2023, 0:59
da PietroBaima
Codice: Seleziona tutto
/******************************************************************************
Pietro Baima
Number to letters ver 0.0
*******************************************************************************/

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

const char *zero[1]={"zero"};
const char *units[10] = {'\0',"uno","due","tre","quattro","cinque","sei","sette","otto","nove"};
const char *teens[10] = {"dieci","undici","dodici","tredici","quattordici","quindici","sedici","diciassette","diciotto","diciannove"};
const char *tens[10]  ={'\0','\0',"venti","trenta","quaranta","cinquanta","sessanta","settanta","ottanta","novanta"};
const char *hundred[1]={"cento"};


int ntoITverbosen(int n, char* verbosen);

int ntoITverbosen(int n, char* verbosen) {

   if (strlen(verbosen)==0 && n==0) {strcpy(verbosen, zero[0]);};
   if (strlen(verbosen)!=0 && (n==1 || n==8) && verbosen[strlen(verbosen)-1]!='o') {verbosen[strlen(verbosen)-1]='\0';};
   if (n>0 && n<10) {strcat(verbosen, units[n]);};
   if (n>9 && n<20) {strcat(verbosen, teens[n-10]);};
   if (n>19 && n<100) {strcat(verbosen, tens[n/10]);ntoITverbosen(n%10,verbosen);};
   if (n>99 && n<1000) {if((n/100)!=1) strcpy(verbosen, units[n/100]);strcat(verbosen, hundred[0]);ntoITverbosen(n%100,verbosen);};
   if (n>999) return (1); else return(0);
}


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

   unsigned int n;
   char termcode;
   
   char *verbosen = malloc(1000);
   
     if( argc<2 ) { //no n
      printf("Usage: %s n[0 to 999]\n",argv[0]);
      return(2);}
 
  strcpy(verbosen, "");
   
   
   n=atoi(argv[1]);
   
   if (n==-1)
      {for (int m=1;m<1000;m++) {ntoITverbosen(m,verbosen);printf("%d is: %s\n",m,verbosen);strcpy(verbosen, ""); };termcode=0;}
   
   else
      {termcode=ntoITverbosen(n,verbosen);
      if (!termcode) printf("%d is: %s\n",n,verbosen); else printf("huge number.\n");}

   free(verbosen);     
   return(termcode);   
}


Per provarlo online cliccare qui.
Per modificarlo cliccate su "Fork This" in alto a sinistra.