I'm working on a program that converts numbers to words, but I'm having problems with the toString() method in the Numbers class. All the methods were given to me, so I could implement; therefore, I can't remove any of them...
number: 4564 --> four thousand and five hundred and sixty four
here's the code Numbers class
package numberstowords;
import java.util.*;
public class Numbers {
//array containing single digits words numbers:0-9
private final String[] SINGLE_DIGITS_WORDS;
//array containing special words words eg:10-19
private final String[] TEEN_DIGITS_WORDS;
//array containing tens words numbers:20-90
private final String[] TEN_DIGITS_WORDS;
private int value, //number to be converted to words
one, //number to store digits
ten, //number to store tens
hundred, //number to store hundred
thousand;//number to store thousand
private String strOut;
//conscructor: Initializing value and arrays
public Numbers(int n)
//getting single digit number
private int getOnes()
{
one = value % 10;
return one;
}
//getting tens numbers
private int getTens()
{
ten = value % 100;
ten /= 10;
return ten;
}
//getting hundreds numbers
private int getHundreds()
{
hundred = value % 1000;
hundred /= 100;
return hundred;
}
//getting thousands numbers
private int getThousands()
{
thousand = value % 10000;
thousand /= 1000;
return thousand;
}
//converting and returning string of ones
private String digitsToString(int one)
{
return SINGLE_DIGITS_WORDS[one];
}
//converting and returning strings of tens and teens
private String tensAndOnesToString(int ten, int one)
{
if(ten == 1)//if number is a teen return, else return tens
{
return TEEN_DIGITS_WORDS[one];
}
return TEN_DIGITS_WORDS[ten-2];
}
//converting and returning strings of hundreds
private String hundredsToString(int hundred)
{
return digitsToString(hundred) + " hundred";
}
private String thousandsToString(int thousand)
{
return digitsToString(thousand) + " thousand";
}
According to your comments, the problem is that you're getting the ones
output for numbers between 11-19
.
Looking at your tensAndOnesToString()
method, it checks whether ten == 1
, for the purpose of identifying the teens
numbers. So, why don't you put a similar check in your if(d4 != 0)
line,
if(d4 != 0 && d3 != 1) // CHANGED THIS LINE
{
if(strOut.equals(""))
strOut = digitsToString(one);
else
{
strOut = strOut +" "+ digitsToString(one);
}
}
So now it will only output a one
number if it (d4
) isn't 0
, and if the tens
(d3
) isn't 1
.
In this short code, I'd used recursive functions to make it simple answer with good performance. I divide the given number to small pieces of math understandable values. This type of divide is math based, which do mostly by the CPU and use smaller amount of memory.
public class NumbersLetter {
private java.util.HashMap<Long, String> hashMap = new java.util.HashMap<>(34);
private long[] dividers = {
1_000_000_000_000_000_000L, 1_000_000_000_000_000L, 1_000_000_000_000L,
1_000_000_000L, 1_000_000L, 1_000L, 100L, 10L, 1L};
public String getNaturalNumbersLetter(long number) {
String regex = "[0-9]+";
if (!Long.toString(number).matches(regex)) {
number = 0;
}
return divideNumber(number);
}
private String getDigitLetter(long digit) {
return hashMap.get(digit);
}
private String addSeparation(boolean addSeperator) {
if (addSeperator) return " and ";
return "";
}
private String divideNumber(long digit) {
//Check if the number is a pure number
// and mapped in our @hashMap
if (hashMap.containsKey(digit)) {
return " " + getDigitLetter(digit);
}
// Start to divide the given number
// to small pieces of math understandable values
// This type of divide is math based
// which do mostly by the CPU and
// use small amount of RAM.
for (long i : dividers) {
/**
* Start divide the given number to smaller pieces
* for example will change 4,321 to
* 4000 , 300 ,20 & 1
* this is one of those formats which is human readable.
* The important thing about this design is that
* I use calculation instead of buffering strings.
* */
if ((digit >= i)) {
if (digit % i == 0) {
//
return divideNumber(digit / i) + divideNumber(i);
} else {
if ((digit / i) == 1) {
return divideNumber(digit / i)
+ divideNumber((digit / i) * i)
+ divideNumber(digit % i);
} else {
return divideNumber((digit / i) * i)
+ divideNumber(digit % i);
}
}
}
}
return "";
}
public NumbersLetter() {
// NumbersLetter Constructor
hashMap.put(0L, "Zero");
hashMap.put(1L, "One");
hashMap.put(2L, "Two");
hashMap.put(3L, "Three");
hashMap.put(4L, "Four");
hashMap.put(5L, "Five");
hashMap.put(6L, "Six");
hashMap.put(7L, "Seven");
hashMap.put(8L, "Eight");
hashMap.put(9L, "Nine");
hashMap.put(10L, "Ten");
hashMap.put(11L, "Eleven");
hashMap.put(12L, "Twelve");
hashMap.put(13L, "Thirteen");
hashMap.put(14L, "Fourteen");
hashMap.put(15L, "Fifteen");
hashMap.put(16L, "Sixteen");
hashMap.put(17L, "Seventeen");
hashMap.put(18L, "Eighteen");
hashMap.put(19L, "Nineteen");
hashMap.put(20L, "Twenty");
hashMap.put(30L, "Thirty");
hashMap.put(40L, "Forty");
hashMap.put(50L, "Fifty");
hashMap.put(60L, "Sixty");
hashMap.put(70L, "Seventy");
hashMap.put(80L, "Eighty");
hashMap.put(90L, "Ninety");
hashMap.put(100L, "Hundred");
hashMap.put(1_000L, "Thousand");
hashMap.put(1_000_000L, "Million");
hashMap.put(1_000_000_000L, "Billion");
hashMap.put(1_000_000_000_000L, "Trillion");
hashMap.put(1_000_000_000_000_000L, "Quadrillion");
hashMap.put(1_000_000_000_000_000_000L, "Quintillion");
}
}
来源:https://stackoverflow.com/questions/10590115/need-help-converting-numbers-to-word-in-java