Algorithm that converts numeric amount into English words

后端 未结 9 1011
眼角桃花
眼角桃花 2020-12-13 21:44

What is the most efficient way to convert numeric amount into English words

e.g. 12 to twelve 127 to one hundred twenty-seven

相关标签:
9条回答
  • 2020-12-13 22:05

    This is some old python code on my hard drive. There might be bugs but it should show the basic idea:

    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)]))
    
    0 讨论(0)
  • 2020-12-13 22:09

    This link provides a detailed explanation of what looks to be a nice approach: http://www.blackwasp.co.uk/NumberToWords.aspx

    0 讨论(0)
  • 2020-12-13 22:10

    That didn't take long. This is an implementation written in Java.

    http://snippets.dzone.com/posts/show/3685

    Code

    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");
        }
    }
    
    0 讨论(0)
提交回复
热议问题