0

I am trying code to print a three digit number in words. But this isn't working if first two digits from right are between 11 & 19 (both including).

Any help?

package com;

import java.util.Stack;

public class TestMain {
public static void main(String[] args) {

Integer i=512;
int temp =i;int pos=1;
Stack<String> stack=new Stack<String>();
while(temp>0){

    int rem=temp%10;
    temp=temp/10;
    if(rem!=0){stack.push(getString(rem, pos));}
    pos*=10;
}
do{
    System.out.print(stack.pop()+" ");
}while(!stack.isEmpty());



}
static String getString(int i,int position){
    String str=null;

    if(position==10){
        i*=position;
    }

    switch(i){
    case 1:
        str= "One";break;

    case 2:
        str= "two";break;
    case 3:
        str= "three";break;
    case 4:
        str= "four";break;
    case 5:
        str= "five";break;
    case 6:
        str= "six";break;
    case 7:
        str= "seven";break;
    case 8:
        str= "eight";break;
    case 9:
        str= "nine";break;
    case 10:
        str= "Ten";break;
    case 11:
        str= "Eleven";break;
    case 12:
        str= "Twelve";break;
    case 13:
        str= "thirteen";break;
    case 14:
        str= "fourteen";break;
    case 15:
        str= "fifteen";break;
    case 16:
        str= "sixteen";break;
    case 17:
        str= "seventeen";break;
    case 18:
        str= "eighteen";break;
    case 19:
        str= "Nineteen";    break;
    case 20:
        str= "twenty";break;
    case 30:
        str= "Thirty";break;
    case 40:
        str= "forty";break;
    case 50:
        str= "Fifty";break;
    case 60:
        str= "sixty";break;
    case 70:
        str= "Seventy";break;
    case 80:
        str= "Eighty";  break;
    case 90:
        str= "Ninety";break;
    case 100:
        str= "Hundred";
        break;
    }
    if(position>=100){
    str=str+ " "+getString(position, 0);
    }
    return str;
}

}

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278

4 Answers4

5

For a three-digit number (negative or positive), you just need to divide it into sections and remember that numbers less than 20 are special (in any block of a hundred). As pseudo-code (well, Python, actually but close enough to pseudo-code), we first define the lookup tables:

nums1 = ["","one","two","three","four","five","six","seven",
         "eight","nine","ten","eleven","twelve","thirteen",
         "fourteen","fifteen","sixteen","seventeen","eighteen",
         "nineteen"]
nums2 = ["","","twenty","thirty","forty","fifty","sixty",
         "seventy","eighty","ninety"]

Note that there's no onety for numbers between ten and nineteen. As previously mentioned, numbers under twenty in each block of a hundred are treated specially.

Then we have the function which first checks the input value and handles negative numbers as a one-level recursive call. It also handles the special case of zero:

def speak (n):
    if n < -999 or n > 999:
        return "out of range"

    if n < 0:
        return "negative " + speak (-n)

    if n == 0:
        return "zero"

Next step is to work out the three digits in the number:

    hundreds = int (n / 100)
    tens = int ((n % 100) / 10)
    ones = n % 10

Hundreds are simple since it's only zero through nine:

    if hundreds > 0:
        retstr = nums1[hundreds] + " hundred"
        if tens != 0 or ones != 0:
            retstr = retstr + " and "
    else:
        retstr = ""

The rest is simply treating values from zero to nineteen as special, otherwise we treat it as Xty Y (like forty two or seventy seven):

    if tens != 0 or ones != 0:
        if tens < 2:
            retstr = retstr + nums1[tens*10+ones]
        else:
            retstr = retstr + nums2[tens]
            if ones != 0:
                retstr = retstr + " " + nums1[ones]
    return retstr

And a quick and dirty test suite at the bottom:

for i in range (-1000, 1001):
    print "%5d %s"%(i, speak (i))

produces:

-1000 out of range
 -999 negative nine hundred and ninety nine
 -998 negative nine hundred and ninety eight
    : 
   -2 negative two
   -1 negative one
    0 zero
    1 one
    2 two
    :
   10 ten
   11 eleven
   12 twelve
    :
  998 nine hundred and ninety eight
  999 nine hundred and ninety nine
 1000 out of range
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • +1 for the English spelling of the numbers (as opposed to the American). To see the difference, compare the outputs for 999 in this solution and the Java solution. [I still remember a book of puzzles in which one of the answers depended on no A's appearing in the spelled out numbers until you reached 1000. No-one in England would get that question correct.] – Jonathan Leffler Nov 12 '09 at 13:23
4

Here is the code in Java:

private static String[] DIGIT_WORDS = {
    "zero", "one", "two", "three", "four",
    "five", "six", "seven", "eight", "nine" };
private static String[] TENS_WORDS = {
    "ten", "twenty", "thirty", "forty", "fifty",
    "sixty", "seventy", "eighty", "ninety" };
private static String[] TEENS_WORDS = {
    "ten", "eleven", "twelve", "thirteen", "fourteen",
    "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };

private static String getHundredWords(int num) {
    if (num > 999 || num < 0)
        throw new IllegalArgumentException(
            "Cannot get hundred word of a number not in the range 0-999");
    if (num == 0) return "zero";        
    String ret = "";
    if (num > 99) {
        ret += DIGIT_WORDS[num / 100] + " hundred ";
        num %= 100;
    }
    if (num < 20 && num > 9) {
        ret += TEENS_WORDS[num % 10];
    } else if (num < 10 && num > 0) {
        ret += DIGIT_WORDS[num];
    } else if (num != 0) {
        ret += TENS_WORDS[num / 10 - 1];
        if (num % 10 != 0) {
        ret += " " + DIGIT_WORDS[num % 10];
    }}

    return ret;
}
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
jjnguy
  • 136,852
  • 53
  • 295
  • 323
  • Before anyone decides to downvote this for providing full solutions for homework, please remember that the homework tag was added *after* this answer, and *not* by the OP. – paxdiablo Nov 12 '09 at 07:39
  • Usually I don't post code like this...but I had actually just written it yesterday for homework. (Thanks pax) – jjnguy Nov 12 '09 at 07:43
  • I'm not going to down-vote either of your answers, but I can't see how this could *NOT* be homework. With or without the `homework` tag. If the OP decides to blindly copy-and-paste this and hand it in as his/her own, I hope the teacher Googles his or her way into this this post. :) – Bart Kiers Nov 12 '09 at 10:43
  • I submit the code as a working example. I hope it is not copied directly into a homework assignment. – jjnguy Nov 12 '09 at 10:48
  • Also, thanks for cleaning the code up pax. – jjnguy Nov 12 '09 at 10:50
2
  • You have to treat zero specially.
  • You are using modulo 10 in the test main program, so you don't see 11-20 in the called function. Actually, it is not clear that you see 20, 30, 40, etc either.
  • Your capitalization is inconsistent; good programmers are paranoid about consistency.
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
2

It's been done and posted so you can benefit:

http://www.rgagnon.com/javadetails/java-0426.html

https://sourceforge.net/projects/numberreader/

goric
  • 11,491
  • 7
  • 53
  • 69
Ryan Cook
  • 9,275
  • 5
  • 38
  • 37