Wednesday, March 30, 2011

Number to word converter

Q: Take a number and give the equivalent number in British English words e.g.

1 = one

21 = twenty one

105 = one hundred and five

56945781 = fifty six million nine hundred and forty five thousand seven hundred and eighty one

etc.. up to 999,999,999 without using a tokenizer, or any external libraries

Working Code:

import java.text.DecimalFormat;

public class NumberToWord {

    private static final String[] tensWords = { "", " ten", " twenty",
            " thirty", " forty", " fifty", " sixty", " seventy", " eighty",
            " ninety" };

    private static final String[] words = { "", " one", " two", " three",
            " four", " five", " six", " seven", " eight", " nine", " ten",
            " eleven", " twelve", " thirteen", " fourteen", " fifteen",
            " sixteen", " seventeen", " eighteen", " nineteen" };

    // Convert Number to word which is less than one thousand   
    private static String convertLessThanOneThousand(int number) {
        String thousandWord;

        if (number % 100 < 20) {
            thousandWord = words[number % 100];
            number /= 100;
        } else {
            thousandWord = words[number % 10];
            number /= 10;

            thousandWord = tensWords[number % 10] + thousandWord;
            number /= 10;
        }
       
        if (number == 0)
            return thousandWord;
       
        return words[number] + " hundred" + thousandWord;
    }

   
    //Converts any number to word between 0 to 999 999 999 999 billions millions
    public static String convertNumberToWord(long number) throws Exception{

        if(number < 0)
        {
            throw new Exception("Negative numbers not supported");
        }
       
        if (number == 0) {
            return "zero";
        }

        String snumber = Long.toString(number);
        if(snumber.length() > 13)
        {
            throw new Exception("Numbers greater than 999 billion are not supported");
        }

        // pad with "0"
        String mask = "000000000000";
       
        // DecimalFormat converts 50 to 000000000050 based on the given mask
        DecimalFormat df = new DecimalFormat(mask);
        snumber = df.format(number);

        StringBuilder result = new StringBuilder();

        // XXXnnnnnnnnn
        int billions = Integer.parseInt(snumber.substring(0, 3));
        // nnnXXXnnnnnn
        int millions = Integer.parseInt(snumber.substring(3, 6));
        // nnnnnnXXXnnn
        int hundredThousands = Integer.parseInt(snumber.substring(6, 9));
        // nnnnnnnnnXXX
        int thousands = Integer.parseInt(snumber.substring(9, 12));

        String wordBillions;
        switch (billions) {
        case 0:
            wordBillions = "";
            break;
        case 1:
            wordBillions = convertLessThanOneThousand(billions) + " billion";
            break;
        default:
            wordBillions = convertLessThanOneThousand(billions) + " billion";
        }

        result.append(wordBillions);

        String wordMillions;
        switch (millions) {
        case 0:
            wordMillions = "";
            break;
        case 1:
            wordMillions = convertLessThanOneThousand(millions) + " million";
            break;
        default:
            wordMillions = convertLessThanOneThousand(millions) + " million";
        }

        result.append(wordMillions);

        String wordHundredThousands;
        switch (hundredThousands) {
        case 0:
            wordHundredThousands = "";
            break;
        case 1:
            wordHundredThousands = "one thousand ";
            break;
        default:
            wordHundredThousands = convertLessThanOneThousand(hundredThousands)+ " thousand";
        }

        result.append(wordHundredThousands);

        result.append(convertLessThanOneThousand(thousands));

        return result.toString();
    }

    public static void main(String[] args) {
       
        String word = "";
        try {
            word = NumberToWord.convertNumberToWord(999999999999L);
        } catch (Exception e) {
            System.out.println("error: "+e.getMessage());
        }
        System.out.println(word);
    }

}

No comments: