1

I am creating a program to convert number to words .The program is working fine but in case of "100500" giving the wrong output instead of "one lakh five hundred" its showing "One Lakh thousand Five hundred". The program is as following

 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.text.DecimalFormat;
 public class CheckRupees {

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

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


   private static String convertLessThanOneThousand(int number) {
    String soFar;

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

  soFar = tensNames[number % 10] + soFar;
  number /= 10;
   }
   if (number == 0) return soFar;
   return numNames[number] + " hundred" + soFar;
  }

    private static String convertLessThanOneThousandForLakhs(int number) {
     String soFar;
     if (number % 100 < 20){
      soFar = numNames[number % 100];
      number /= 100;
        }
        else {
        soFar = numNames[number % 10];
        number /= 10;

        soFar = tensNames[number % 10] + soFar;
        number /= 10;
        }
        if (number == 0) return soFar;
       {
      return numNames[number] + " lakh" + soFar;

      }
     }

     public static String convert(long number) {
     // 0 to 999 999 999 999
     if (number == 0) { return "zero"; }

     String snumber = Long.toString(number);

     // pad with "0"
    String mask = "000000000000";
    DecimalFormat df = new DecimalFormat(mask);
    snumber = df.format(number);

     // 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 tradBillions;
     switch (billions) {
     case 0:
     tradBillions = "";
     break;
     case 1 :
     tradBillions = convertLessThanOneThousand(billions)
      + " billion ";
    break;
  default :
  tradBillions = convertLessThanOneThousand(billions)
  + " billion ";
   }
 String result =  tradBillions;

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

 String tradHundredThousands;
 switch (hundredThousands) {
 case 0:
  tradHundredThousands = "";
  break;
  case 1 :
  tradHundredThousands = "one thousand ";
  break;
  default :
  tradHundredThousands =     convertLessThanOneThousandForLakhs(hundredThousands)
     + " thousand";
}
result =  result + tradHundredThousands;

String tradThousand;
tradThousand = convertLessThanOneThousand(thousands);
result =  result + tradThousand;

// remove extra spaces!
return result.replaceAll("^\\s+", "").replaceAll("\\b\\s{2,}\\b", " ");

}


 public static void main(String[] args) {


  int xValue=200500;
    System.out.println(CheckRupees.convert(xValue));
  } 
}
adesh singh
  • 1,727
  • 9
  • 38
  • 70
  • 1
    Possible duplicate of [What is a debugger and how can it help me diagnose problems?](http://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) – aUserHimself Mar 22 '17 at 14:03
  • Its Working now , added result=result.replaceAll("lakh thousand","lakh"); – adesh singh Mar 22 '17 at 14:27
  • 2
    You should fix the problem by fixing the problem instead of adding post-processing code trying to hide the symptom. – Holger Mar 22 '17 at 14:30
  • If you want the words in Indian numbering system, why do you also have millions? Or is 1 000 000 supposed to be 1 million and not 10 lakh? – James Z Mar 23 '17 at 05:02

2 Answers2

2

You should implement your operation in a more structured way, instead of creating a special case for every name. Further, there is no point in using these combinations of formatting and substring operations, when Java has numerical comparison operators.

E.g.

private static final String[] LARGE_NAMES = {
        "billion",  "million",   "lakh", "thousand", "hundred"
};
private static final int[] LARGE_FACTORS = {
    1_000_000_000,  1_000_000,  100_000,      1_000,       100
};
private static final String[] TENS_NAMES = {
    "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"
};
private static final String[] SMALL_NAMES = {
    "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
    "eleven", "twelve", "thirteen", "fourteen", "fifteen",
    "sixteen", "seventeen", "eighteen", "nineteen"
};
public static String toName(int number) {
    return number==0? "zero": appendName(number, new StringBuilder()).toString();
}

private static StringBuilder appendName(int number, StringBuilder sb) {
    if(number >= LARGE_FACTORS[LARGE_FACTORS.length-1]) {
        for(int i = 0; i < LARGE_FACTORS.length; i++) {
            int f = LARGE_FACTORS[i];
            if(number >= f) {
                int quantity = number/f;
                appendName(quantity, sb).append(' ').append(LARGE_NAMES[i]);
                number -= quantity*f;
            }
        }
    }
    if(number>0) {
        if(sb.length()>0) sb.append(' ');
        if(number>SMALL_NAMES.length) {
            int tenth = number/10;
            sb.append(TENS_NAMES[tenth-1]);
            number -= tenth*10;
            if(number == 0) return sb;
            sb.append(' ');
        }
        sb.append(SMALL_NAMES[number-1]);
    }
    return sb;
}
Holger
  • 285,553
  • 42
  • 434
  • 765
0

This line is adding 'Thousand' for your input value:

    default:
        tradHundredThousands = convertLessThanOneThousandForLakhs(hundredThousands)
                + " thousand";

You can fix it by adding one more condition on variable hundredThousands. And add 'thousand' only when hundredThousands is less than 100.

ManishKr
  • 211
  • 2
  • 9