Qual è il modo più efficiente per convertire l'importo numerico in ingleseAlgoritmo che converte l'importo numerico in inglese
ad es. Da 12 a 12 da 127 a centoventisette
Qual è il modo più efficiente per convertire l'importo numerico in ingleseAlgoritmo che converte l'importo numerico in inglese
ad es. Da 12 a 12 da 127 a centoventisette
Non ci è voluto molto. Questa è un'implementazione scritta in Java.
http://snippets.dzone.com/posts/show/3685
public class IntToEnglish {
static String[] to_19 = { "zero", "one", "two", "three", "four", "five", "six",
"seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen",
"fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
static String[] tens = { "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};
static String[] denom = { "",
"thousand", "million", "billion", "trillion", "quadrillion",
"quintillion", "sextillion", "septillion", "octillion", "nonillion",
"decillion", "undecillion", "duodecillion", "tredecillion", "quattuordecillion",
"sexdecillion", "septendecillion", "octodecillion", "novemdecillion", "vigintillion" };
public static void main(String[] argv) throws Exception {
int tstValue = Integer.parseInt(argv[0]);
IntToEnglish itoe = new IntToEnglish();
System.out.println(itoe.english_number(tstValue));
/* for (int i = 0; i < 2147483647; i++) {
System.out.println(itoe.english_number(i));
} */
}
// convert a value < 100 to English.
private String convert_nn(int val) throws Exception {
if (val < 20)
return to_19[val];
for (int v = 0; v < tens.length; v++) {
String dcap = tens[v];
int dval = 20 + 10 * v;
if (dval + 10 > val) {
if ((val % 10) != 0)
return dcap + "-" + to_19[val % 10];
return dcap;
}
}
throw new Exception("Should never get here, less than 100 failure");
}
// convert a value < 1000 to english, special cased because it is the level that kicks
// off the < 100 special case. The rest are more general. This also allows you to
// get strings in the form of "forty-five hundred" if called directly.
private String convert_nnn(int val) throws Exception {
String word = "";
int rem = val/100;
int mod = val % 100;
if (rem > 0) {
word = to_19[rem] + " hundred";
if (mod > 0) {
word = word + " ";
}
}
if (mod > 0) {
word = word + convert_nn(mod);
}
return word;
}
public String english_number(int val) throws Exception {
if (val < 100) {
return convert_nn(val);
}
if (val < 1000) {
return convert_nnn(val);
}
for (int v = 0; v < denom.length; v++) {
int didx = v - 1;
int dval = new Double(Math.pow(1000, v)).intValue();
if (dval > val) {
int mod = new Double(Math.pow(1000, didx)).intValue();
int l = val/mod;
int r = val - (l * mod);
String ret = convert_nnn(l) + " " + denom[didx];
if (r > 0) {
ret = ret + ", " + english_number(r);
}
return ret;
}
}
throw new Exception("Should never get here, bottomed out in english_number");
}
}
Un modo per raggiungere questo obiettivo sarebbe quello di utilizzare guardare in alto tabelle. Sarebbe in qualche modo una forza bruta, ma facile da configurare. Ad esempio, potresti avere le parole per 0-99 in una tabella, quindi una tabella per decine, centinaia, migliaia, ecc. Alcuni semplici calcoli ti daranno l'indice della parola che ti serve da ogni tabella.
Sarebbe un enorme spreco di memoria. – Christian
Sono d'accordo con la tua valutazione, ma ho usato il termine "forza bruta" nella mia descrizione. Inoltre, esistono altre risposte per questa stessa domanda che utilizzano un approccio alla tabella di ricerca, compresa la risposta accettata. Non sono sicuro del motivo per cui il tuo commento si applica solo alla mia risposta. – nathan
.) Fare una biblioteca di tutti i numeri & posizioni (ad esempio 1 ha altra notazione di 10, un altro di 100, ecc) .) Fare un elenco di eccezioni (ad esempio per 12) ed essere consapevoli, che nel vostro algoritmo, la stessa eccezione è per 112, 1012 ecc.
se si desidera una velocità ancora maggiore, creare un numero memorizzato nella cache di numeri necessari.
Questo link fornisce una spiegazione dettagliata di quello che sembra essere un approccio piacevole: http://www.blackwasp.co.uk/NumberToWords.aspx
Nota alcune regole:
digit place
come "tremila".È possibile ottenere il posto di un numero tramite la divisione piano di interi: 532/100 -> 5
Questo è un po 'vecchio codice python sul mio disco rigido. Ci potrebbe essere bug ma dovrebbe mostrare l'idea di base:
class Translator:
def transformInt(self, x):
translateNumbers(0,[str(x)])
def threeDigitsNumber(self,number):
snumber=self.twoDigitsNumber(number/100)
if number/100!=0:
snumber+=" hundred "
snumber+self.twoDigitsNumber(number)
return snumber+self.twoDigitsNumber(number)
def twoDigitsNumber(self,number):
snumber=""
if number%100==10:
snumber+="ten"
elif number%100==11:
snumber+="eleven"
elif number%100==12:
snumber+="twelve"
elif number%100==13:
snumber+="thirteen"
elif number%100==14:
snumber+="fourteen"
elif number%100==15:
snumber+="fifteen"
elif number%100==16:
snumber+="sixteen"
elif number%100==17:
snumber+="seventeen"
elif number%100==18:
snumber+="eighteen"
elif number%100==19:
snumber+="nineteen"
else:
if (number%100)/10==2:
snumber+="twenty-"
elif (number%100)/10==3:
snumber+="thirty-"
elif (number%100)/10==4:
snumber+="forty-"
elif (number%100)/10==5:
snumber+="fifty-"
elif (number%100)/10==6:
snumber+="sixty-"
elif (number%100)/10==7:
snumber+="seventy-"
elif (number%100)/10==8:
snumber+="eighty-"
elif (number%100)/10==9:
snumber+="ninety-"
if (number%10)==1:
snumber+="one"
elif (number%10)==2:
snumber+="two"
elif (number%10)==3:
snumber+="three"
elif (number%10)==4:
snumber+="four"
elif (number%10)==5:
snumber+="five"
elif (number%10)==6:
snumber+="six"
elif (number%10)==7:
snumber+="seven"
elif (number%10)==8:
snumber+="eight"
elif (number%10)==9:
snumber+="nine"
elif (number%10)==0:
if snumber!="":
if snumber[len(snumber)-1]=="-":
snumber=snumber[0:len(snumber)-1]
return snumber
def translateNumbers(self,counter,words):
if counter+1<len(words):
self.translateNumbers(counter+1,words)
else:
if counter==len(words):
return True
k=0
while k<len(words[counter]):
if (not (ord(words[counter][k])>47 and ord(words[counter][k])<58)):
break
k+=1
if (k!=len(words[counter]) or k==0):
return 1
number=int(words[counter])
from copy import copy
if number==0:
self.translateNumbers(counter+1,copy(words[0:counter]+["zero"]+words[counter+1:len(words)]))
self.next.append(copy(words[0:counter]+["zero"]+words[counter+1:len(words)]))
return 1
if number<10000:
self.translateNumbers(counter+1,copy(words[0:counter]
+self.seperatewords(self.threeDigitsNumber(number))
+words[counter+1:len(words)]))
self.next.append(copy(words[0:counter]
+self.seperatewords(self.threeDigitsNumber(number))
+words[counter+1:len(words)]))
if number>999:
snumber=""
if number>1000000000:
snumber+=self.threeDigitsNumber(number/1000000000)+" billion "
number=number%1000000000
if number>1000000:
snumber+=self.threeDigitsNumber(number/1000000)+" million "
number=number%1000000
if number>1000:
snumber+=self.threeDigitsNumber(number/1000)+" thousand "
number=number%1000
snumber+=self.threeDigitsNumber(number)
self.translateNumbers(counter+1,copy(words[0:counter]+self.seperatewords(snumber)
+words[counter+1:len(words)]))
self.next.append(copy(words[0:counter]+self.seperatewords(snumber)
+words[counter+1:len(words)]))
Questa soluzione non tenta di tenere conto di spazi finali, ma è abbastanza veloce.
typedef const char* cstring;
using std::string;
using std::endl;
std::ostream& GetOnes(std::ostream &output, int onesValue)
{
cstring ones[] = { "zero", "one", "two", "three", "four", "five", "six",
"seven", "eight", "nine" };
output << ones[onesValue];
return output;
}
std::ostream& GetSubMagnitude(std::ostream &output, int subMagnitude)
{
cstring tens[] = { "zeroty", "ten", "twenty", "thirty", "fourty", "fifty",
"sixty", "seventy", "eighty", "ninety"};
if (subMagnitude/100 != 0)
{
GetOnes(output, subMagnitude/100) << " hundred ";
GetSubMagnitude(output, subMagnitude - subMagnitude/100 * 100);
}
else
{
if (subMagnitude >= 20)
{
output << tens[subMagnitude/10] << " ";
GetOnes(output, subMagnitude - subMagnitude/10 * 10);
}
else if (subMagnitude >= 10)
{
cstring teens[] = { "ten", "eleven", "twelve", "thirteen",
"fourteen", "fifteen", "sixteen", "seventeen",
"eighteen", "nineteen" };
output << teens[subMagnitude - 10] << " ";
}
else
{
GetOnes(output, subMagnitude) << " ";
}
}
return output;
}
std::ostream& GetLongNumber(std::ostream &output, double input)
{
cstring magnitudes[] = {"", "hundred", "thousand", "million", "billion",
"trillion"};
double magnitudeTests[] = {1, 100.0, 1000.0, 1000000.0, 1000000000.0,
1000000000000.0 };
int magTestIndex = 0;
while (floor(input/magnitudeTests[magTestIndex++]) != 0);
magTestIndex -= 2;
if (magTestIndex >= 0)
{
double subMagnitude = input/magnitudeTests[magTestIndex];
GetSubMagnitude(output, (int)subMagnitude);
if (magTestIndex) {
output << magnitudes[magTestIndex] << " ";
double remainder = input - (floor(input/
magnitudeTests[magTestIndex]) *
magnitudeTests[magTestIndex]);
if (floor(remainder) > 0)
{
GetLongNumber(output, remainder);
}
}
}
else
{
output << "zero";
}
return output;
}
Ovviamente, le dichiarazioni di non responsabilità includono che non rappresentano numeri superiori a 999,999,999,999,999, non fa frazioni e non gestisce numeri negativi. Abbastanza facile da aggiungere, ma devi fermarti ad un certo punto. –
Inizia risolvendo 1-99, con un elenco di numeri per 1-20, e poi 30, 40, ..., 90. Quindi aggiungere centinaia di ottenere 1-999. Quindi usa quella routine per dare il numero di ciascuna potenza di 1.000 per il massimo che vuoi (penso che la più alta nomenclatura standard sia per decillion, che è 10^33).
Un piccolo avvertimento è che è un po 'complicato ottenere gli spazi vuoti in tutti i casi se si sta tentando di iniziare e finire senza uno spazio in eccesso. La soluzione facile è mettere uno spazio vuoto dopo ogni parola e poi rimuovere lo spazio vuoto finale quando hai finito. Se si tenta di essere più precisi mentre si costruisce la stringa, è probabile che si finisca con spazi vuoti mancanti o spazi in eccesso.
Questo è part of Common Lisp!
Here's how GNU CLISP does it e here's how CMUCL does it (più facile da leggere, IMHO).
Fare un code search per "formato milioni di miliardi" ne mostrerà molti.
O in inglese cento ** e ** ventisette. :) –
@Philip, il "e" è sbagliato se parli di inglese corretto. "E" è per le parti frazionarie. –
@David - In inglese britannico, se un numero include un numero più piccolo ** e ** li unisce. Come nel 2010 - duemiladieci. Un'altra variazione è in valuta quando £ 1,20 è una sterlina venti o una sterlina e venti pence. Se sei annoiato puoi visualizzare http://www.english-at-home.com/speaking/saying-dates-and-numbers-in-english/ –