Thursday, August 7, 2014

Beyond Hello World.

Hi, I got a question from someone to write program to convert Number to word.
I thought to write an simple looking algorithm, but when i started doing this it was not so simple.

Let me rephrase the question.

Convert  Number in the Range of [-999999 , 999999] to words.

Example :  Input no = 45678

output =  Forty Five Thousand Six Hundred And Seventy Eight

Input = -43675
output = Minus Forty Three Thousand Six Hundred And Seventy Five


Program:

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;

public class StringManupulation {

    private static  Map<Integer,String> valueWordMap = new HashMap<>();
   
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
       
        String number;
        while(true){
        System.out.println("Please enter the Numeric No Between -999999 and 999999 : ");
        number = scan.nextLine();
        if(checkIfNumberValid(number)){
            break;
        }
        }
        convertNumberToWords(Integer.valueOf(number));
       
    }

    private static void convertNumberToWords(Integer number) {
        TreeMap<Integer,Integer> faceValueMap = new TreeMap<>();
       
        prepareValueWordMap();
        boolean isNoNegative = false;
        if(String.valueOf(number).contains("-")){
            number = Math.abs(number);
            isNoNegative=true;
           
        }
        Integer baseNo = getBaseNo(String.valueOf(number).length());
        boolean reachedEnd=false;
        int length=0;
        while(baseNo>=1 && !reachedEnd){
            if(baseNo==1){
                reachedEnd=true;
            }
            faceValueMap.put(baseNo, number%(baseNo*10)/baseNo);
            length++;
            baseNo = getBaseNo(String.valueOf(number).substring(length).length());
           
        }
        String word="";
        Integer temp = null;
        String appender="";
        String andString=" And";
        int index=-1;
        for(Integer key : faceValueMap.descendingKeySet()){
            index++;
            if(faceValueMap.get(key)!=0 || null!=temp){
                if(key==1000000 || key == 10000 || key==10){
                    temp=faceValueMap.get(key);
                    continue;
                }
                if(key!=1){
                    appender = " " + valueWordMap.get(key);
                    andString="";
                }
                if((checkTrailingZeros(number,index) || key==1) && !word.isEmpty()){
                    andString=" And";
                }
               
                if(null!=temp){
                   
                    word =  word + andString + " " + valueWordMap.get(temp*10) + " " + valueWordMap.get(faceValueMap.get(key)) + appender;
                }
                else{
                    word =  word + andString +" " + valueWordMap.get(faceValueMap.get(key)) + appender;
                }
                temp=null;
            }
            appender="";
        }
        if(isNoNegative){
            word = "Minus" + word;
        }
        System.out.println(word);
    }

    private static boolean checkIfNumberValid(String number) {
        if(number.length()<8){
            try{
                Integer.parseInt(number);
            }
            catch(Exception ex){
                System.out.println("Invalid No");
                return false;
            }
        Integer i = Integer.valueOf(number);
        if(!(i>=-999999 && i<=999999)){
            return false;
        }
        }
        else{
            return false;
        }
        return true;
       
    }

    private static boolean checkTrailingZeros(Integer number, int index) {
        for(int i = index+1;i<String.valueOf(number).length();i++){
            if(String.valueOf(number).charAt(i)=='0'){
                continue;
            }
            else{
                return false;
            }
        }
        return true;
    }

    private static void prepareValueWordMap() {
        valueWordMap.put(100000, "Lakh");
        valueWordMap.put(10000, "Ten Thousand");
        valueWordMap.put(1000, "Thousand");
        valueWordMap.put(100, "Hundred");
        valueWordMap.put(10, "Ten");   
        valueWordMap.put(1, "One");   
        valueWordMap.put(2, "Two");   
        valueWordMap.put(3, "Three");   
        valueWordMap.put(4, "Four");   
        valueWordMap.put(5, "Five");   
        valueWordMap.put(6, "Six");   
        valueWordMap.put(7, "Seven");   
        valueWordMap.put(8, "Eight");   
        valueWordMap.put(9, "Nine");   
        valueWordMap.put(11, "Eleven");    ;
        valueWordMap.put(12, "Twelve");   
        valueWordMap.put(13, "Thirteen");   
        valueWordMap.put(14, "Fourteen");   
        valueWordMap.put(15, "Fifteen");   
        valueWordMap.put(16, "Sixteen");   
        valueWordMap.put(17, "Seventeen");   
        valueWordMap.put(18, "Eighteen");   
        valueWordMap.put(19, "Nineteen");   
        valueWordMap.put(20, "Twenty");   
        valueWordMap.put(30, "Thirty");   
        valueWordMap.put(40, "Forty");   
        valueWordMap.put(50, "Fifty");   
        valueWordMap.put(60, "Sixty");   
        valueWordMap.put(70, "Seventy");   
       
        valueWordMap.put(80, "Eighty");   
        valueWordMap.put(90, "Ninety");   
        valueWordMap.put(0, "");   
       
       
    }

    private static Integer getBaseNo(double d) {
       
        return (int) Math.pow(10, d-1);
    }

}

2 comments:

  1. Nice article Sadiq !! Good Start...

    ReplyDelete
    Replies
    1. Thanks... Hopefully, will continue this. Need your feedback always. :)

      Delete