Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

funzione conversione numero in lettere

Progetti, interfacciamento, discussioni varie su questa piattaforma.

Moderatori: Foto UtenteMassimoB, Foto UtenteWALTERmwp, Foto Utentexyz

0
voti

[11] Re: funzione conversione numero in lettere

Messaggioda Foto Utentedadduni » 18 feb 2023, 23:53

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
Avatar utente
Foto Utentedadduni
1.963 2 7 12
Expert EY
Expert EY
 
Messaggi: 1331
Iscritto il: 23 mag 2014, 16:26

0
voti

[12] Re: funzione conversione numero in lettere

Messaggioda Foto UtenteMarcoD » 19 feb 2023, 9:15

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.
Avatar utente
Foto UtenteMarcoD
11,6k 5 9 13
Master EY
Master EY
 
Messaggi: 6279
Iscritto il: 9 lug 2015, 16:58
Località: Torino

0
voti

[13] Re: funzione conversione numero in lettere

Messaggioda Foto Utentedjnz » 19 feb 2023, 14:47

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:
Una domanda ben posta è già mezza risposta.
Avatar utente
Foto Utentedjnz
975 1 4 5
Expert
Expert
 
Messaggi: 542
Iscritto il: 26 lug 2020, 14:52

0
voti

[14] Re: funzione conversione numero in lettere

Messaggioda Foto UtenteEtemenanki » 19 feb 2023, 17:10

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:
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.
Avatar utente
Foto UtenteEtemenanki
6.409 3 5 10
Master
Master
 
Messaggi: 4111
Iscritto il: 2 apr 2021, 23:42
Località: Dalle parti di un grande lago ... :)

0
voti

[15] Re: funzione conversione numero in lettere

Messaggioda Foto Utentedjnz » 19 feb 2023, 18:07

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.
Una domanda ben posta è già mezza risposta.
Avatar utente
Foto Utentedjnz
975 1 4 5
Expert
Expert
 
Messaggi: 542
Iscritto il: 26 lug 2020, 14:52

1
voti

[16] Re: funzione conversione numero in lettere

Messaggioda Foto Utentenicsergio » 19 feb 2023, 18:56

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"));
Avatar utente
Foto Utentenicsergio
4.356 3 9 13
Master
Master
 
Messaggi: 844
Iscritto il: 1 gen 2020, 16:42

0
voti

[17] Re: funzione conversione numero in lettere

Messaggioda Foto UtenteGioArca67 » 19 feb 2023, 21:50

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
Avatar utente
Foto UtenteGioArca67
3.426 4 5 9
Master
Master
 
Messaggi: 3311
Iscritto il: 12 mar 2021, 9:36

0
voti

[18] Re: funzione conversione numero in lettere

Messaggioda Foto UtenteGioArca67 » 19 feb 2023, 22:22

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
Avatar utente
Foto UtenteGioArca67
3.426 4 5 9
Master
Master
 
Messaggi: 3311
Iscritto il: 12 mar 2021, 9:36

0
voti

[19] Re: funzione conversione numero in lettere

Messaggioda Foto Utentestefanopc » 19 feb 2023, 22:23

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
600 Elettra
Avatar utente
Foto Utentestefanopc
9.569 5 8 13
Master EY
Master EY
 
Messaggi: 3832
Iscritto il: 4 ago 2020, 9:11

0
voti

[20] Re: funzione conversione numero in lettere

Messaggioda Foto UtentePietroBaima » 20 feb 2023, 0:59

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.
Generatore codice per articoli:
nomi
Sul forum:
[pigreco]=π
[ohm]=Ω
[quadrato]=²
[cubo]=³
Avatar utente
Foto UtentePietroBaima
88,2k 7 12 13
G.Master EY
G.Master EY
 
Messaggi: 11911
Iscritto il: 12 ago 2012, 1:20
Località: Londra

PrecedenteProssimo

Torna a Arduino

Chi c’è in linea

Visitano il forum: Nessuno e 4 ospiti