Number To Words Java
Number To Words Java
I have a homework in my programming class that makes a program that can change numbers(Integer) to Words(String).
We can only use If else or Switch statement and my code is already working but My teacher said that my code is not correct because I use private static String numberToWord(int number) and String unitsArray he said that I may use only the things that we discuss in our class so I need to reconstruct my code.
Please help me to reconstruct my code. I'm so confused right now I can't think properly.
Integer
String
Switch
private static String numberToWord(int number)
String unitsArray
This is my code in java:
public static void main(String args)
int number = 0;
Scanner scanner = new Scanner(System.in);
System.out.print("Please type a number(max upto 9 digits)");
// read the number
number = scanner.nextInt();
if (number == 0)
System.out.print("Number in words: Zero");
else
System.out.print(numberToWord(number));
private static String numberToWord(int number)
// variable to hold string representation of number
String words = "";
String unitsArray = "zero", "one", "two", "three", "four", "five", "six",
"seven", "eight", "nine", "ten", "eleven", "twelve",
"thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
"eighteen", "nineteen" ;
String tensArray = "zero", "ten", "twenty", "thirty", "forty", "fifty",
"sixty", "seventy", "eighty", "ninety" ;
if (number == 0)
return "zero";
// add minus before conversion if the number is less than 0
if (number < 0)
// convert the number to a string
String numberStr = "" + number;
// remove minus before the number
numberStr = numberStr.substring(1);
// add minus before the number and convert the rest of number
return "minus " + numberToWord(Integer.parseInt(numberStr));
// check if number is divisible by 1 million
if ((number / 1000000) > 0)
words += numberToWord(number / 1000000) + " million ";
number %= 1000000;
// check if number is divisible by 1 thousand
if ((number / 1000) > 0)
words += numberToWord(number / 1000) + " thousand ";
number %= 1000;
// check if number is divisible by 1 hundred
if ((number / 100) > 0)
words += numberToWord(number / 100) + " hundred ";
number %= 100;
if (number > 0)
// check if number is within teens
if (number < 20)
// fetch the appropriate value from unit array
words += unitsArray[number];
else
// fetch the appropriate value from tens array
words += tensArray[number / 10];
if ((number % 10) > 0)
words += "-" + unitsArray[number % 10];
return words;
}
We do not know what you did not discuss in your class. Methods? static methods? Recusivity? Arrays?
– StephaneM
Sep 17 '18 at 11:27
So what did your teacher want you to use? did he give any indication? what was discussed in your class?
– Raj
Sep 17 '18 at 11:28
2 Answers
2
you just need to check how the switch statement works and do not use the function, but put everything in the main function.
I'll give you a hint:
switch(number){
case 1: "one";
break;
I think the question is more about not using
static methods...– Carlos Heuberger
Sep 17 '18 at 11:36
static
It is good, that this code works fine, but I can see some problems in it:
You use recursion (i.e. loops). Therefore each time when you type str = str1 + str2 you have three strings in the JVM. You should use StringBuilder instead and at the end, convert it to the final string.
str = str1 + str2
In numberToWord method, you declare two arrays: unitsArray and tensArray. Every time, when you call this method, these array are been initialized again. If you use static method, just use static initialization block to declare these arrays only once and reuse it.
numberToWord
unitsArray
tensArray
static
Scanner scanner scanner should be closed (it contains close() method). It is not critical for the scanner, but anyway, this is must have: when you use resource, do release it before quit.
Scanner scanner
close()
try (Scanner scan = new Scanner(System.in))
// payload
1031 is one thousand and thirty one
Your client code looks like:
number = scanner.nextInt();
if (number == 0)
System.out.print("Number in words: Zero");
else
System.out.print(numberToWord(number));
This is very bad practice. This check should be incapsulated in your logic. Client should not worry about corner cases: System.out.print(numberToWord(scanner.nextInt())).
System.out.print(numberToWord(scanner.nextInt()))
Actually, I do not mind to use static in some cases. But in the given example, your teacher is right: you have a task convert number to the string representation and this task contains some logic and internal constants. It is better to incapsulate it into separate class. It could be static class with only one public method String convert(long val) (but this is old-style and not OOP). You could create separate class, move your static method into it and remove static. This is enough (plus I would initialize array once, in the constructor). In general this is enough.
static
convert number to the string representation
static
String convert(long val)
static
P.S.
Could I give you my solution to this problem. I split this task into two steps: first - convert the string into list of simple numbers (like one, ten, hundred, million) and then using predefined dictionary, convert these simple numbers into final string.
E.g.
value: 1001
1001
numbers: [1, 1000, 1]
[1, 1000, 1]
results: one thousand and one
one thousand and one
My solution:
public final class NumberToWordConverter
private final Long AND = null;
private final Map<Long, String> map = new HashMap<>();
map.put(AND, "and");
map.put(0L, "zero");
map.put(1L, "one");
map.put(2L, "two");
map.put(3L, "three");
map.put(4L, "four");
map.put(5L, "five");
map.put(6L, "six");
map.put(7L, "seven");
map.put(8L, "eight");
map.put(9L, "nine");
map.put(10L, "ten");
map.put(11L, "eleven");
map.put(12L, "twelve");
map.put(13L, "thirteen");
map.put(14L, "fourteen");
map.put(15L, "fifteen");
map.put(16L, "sixteen");
map.put(17L, "seventeen");
map.put(18L, "eighteen");
map.put(19L, "nineteen");
map.put(20L, "twenty");
map.put(30L, "thirty");
map.put(40L, "forty");
map.put(50L, "fifty");
map.put(60L, "sixty");
map.put(70L, "seventy");
map.put(80L, "eighty");
map.put(90L, "ninety");
map.put(100L, "hundred");
map.put(1000L, "thousand");
map.put(1000000L, "million");
map.put(1000000000L, "billion");
public String numberToWords(long val)
String str = parts(Math.abs(val), 1, new LinkedList<>()).stream()
.map(map::get)
.collect(Collectors.joining(" "));
return val < 0 ? "minus " + str : str;
private Deque<Long> parts(long val, long mul, Deque<Long> queue)
if (val >= 1000)
parts(val / 1000, mul * 1000, queue);
if (val % 1000 > 0)
parts(val % 1000, mul, queue);
else if (val <= 20)
if (mul == 1)
queue.add(AND);
queue.add(val);
if (mul > 1)
queue.add(mul);
else if (val < 100)
if (mul == 1)
queue.add(AND);
queue.add(val / 10 * 10);
if (val % 10 > 0)
queue.add(val % 10);
if (mul > 1)
queue.add(mul);
else
queue.add(val / 100);
queue.add(100L);
if (val % 100 > 0)
parts(val % 100, 1, queue);
if (mul > 1)
queue.add(mul);
return queue;
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy
If the methods cannot be static then have to be instance methods. You need to create an instance of your class, and then call the method on it.
– m0skit0
Sep 17 '18 at 11:26