Added number to word converter

This commit is contained in:
Ziver Koc 2015-12-03 16:16:12 +01:00
parent 6dbc31b521
commit 89d8834d80
2 changed files with 164 additions and 0 deletions

View file

@ -0,0 +1,92 @@
package zutil.converters;
import java.util.HashMap;
public class NumberToWordsConverter {
private static final String ZERO_STRINGS = "zero";
// Indexes to lookup
private static final int[] NUMERIC_INDEXES = new int[]{
9,/*1000 000 000*/
6,/*1000 000*/
3,/*1000*/
2 /*100*/};
private static final HashMap<Long, String> NUMERIC_STRINGS;
static{
NUMERIC_STRINGS = new HashMap<>();
NUMERIC_STRINGS.put(1l, "one");
NUMERIC_STRINGS.put(2l, "two");
NUMERIC_STRINGS.put(3l, "three");
NUMERIC_STRINGS.put(4l, "four");
NUMERIC_STRINGS.put(5l, "five");
NUMERIC_STRINGS.put(6l, "six");
NUMERIC_STRINGS.put(7l, "seven");
NUMERIC_STRINGS.put(8l, "eight");
NUMERIC_STRINGS.put(9l, "nine");
NUMERIC_STRINGS.put(10l, "ten");
NUMERIC_STRINGS.put(11l, "eleven");
NUMERIC_STRINGS.put(12l, "twelve");
NUMERIC_STRINGS.put(13l, "thirteen");
NUMERIC_STRINGS.put(14l, "fourteen");
NUMERIC_STRINGS.put(15l, "fifteen");
NUMERIC_STRINGS.put(16l, "sixteen");
NUMERIC_STRINGS.put(17l, "seventeen");
NUMERIC_STRINGS.put(18l, "eightteen");
NUMERIC_STRINGS.put(19l, "nineteen");
NUMERIC_STRINGS.put(20l, "twenty");
NUMERIC_STRINGS.put(30l, "thirty");
NUMERIC_STRINGS.put(40l, "forty");
NUMERIC_STRINGS.put(50l, "fifty");
NUMERIC_STRINGS.put(60l, "sixty");
NUMERIC_STRINGS.put(70l, "seventy");
NUMERIC_STRINGS.put(80l, "eighty");
NUMERIC_STRINGS.put(90l, "ninety");
NUMERIC_STRINGS.put(100l, "hundred");
NUMERIC_STRINGS.put(1_000l, "thousand");
NUMERIC_STRINGS.put(1000_000l, "million");
NUMERIC_STRINGS.put(1000_000_000l, "billion");
}
/**
* Given an integer in the range -20 to 20 will return a String with
* that number converted to words. For example, an input of 15 results in
* an output of "fifteen". An input of -4 returns "minus four".
*
* @param num a number to be converted to words.
* @return the number as words.
*/
public String convert(int num) {
if (num == 0)
return ZERO_STRINGS;
long tmpNum = num;
StringBuilder buffer = new StringBuilder();
if (tmpNum < 0){ // Negative number
tmpNum *= -1;
buffer.append("minus ");
}
for(int i : NUMERIC_INDEXES){
long pow = (int)Math.pow(10, i);
if (tmpNum >= pow){
long numberAtIndex = tmpNum/pow; // The number at position 3
tmpNum -= numberAtIndex*pow;
buffer.append( convert((int)numberAtIndex) ).append(" ");
buffer.append( NUMERIC_STRINGS.get( pow ) ).append(" ");
}
}
if (tmpNum >= 20){ // second number in the integer
long numberAtIndex = ((tmpNum % 100)/10)*10; // The number at position 2
tmpNum -= numberAtIndex;
buffer.append( NUMERIC_STRINGS.get(numberAtIndex) ).append(" ");
}
if (NUMERIC_STRINGS.containsKey(tmpNum))
buffer.append(NUMERIC_STRINGS.get(tmpNum));
return buffer.toString().trim();
}
}

View file

@ -0,0 +1,72 @@
package zutil.test;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import zutil.converters.NumberToWordsConverter;
@RunWith(Parameterized.class)
public class NumberToWordsConverterTest {
@Parameters
public static Collection<Object[]> parameters() {
Object[][] data = new Object[][] {
{-77, "minus seventy seven"}
, {-2, "minus two"}
, {1, "one"}
, {0, "zero"}
, {7, "seven"}
, {11, "eleven"}
, {12, "twelve"}
, {17, "seventeen"}
, {20, "twenty"}
, {21, "twenty one"}
, {23, "twenty three"}
, {25, "twenty five"}
, {30, "thirty"}
, {34, "thirty four"}
, {50, "fifty"}
, {70, "seventy"}
, {100, "one hundred"}
, {110, "one hundred ten"}
, {131, "one hundred thirty one"}
, {222, "two hundred twenty two"}
, {1000, "one thousand"}
, {10_000, "ten thousand"}
, {100_000, "one hundred thousand"}
, {1000_000, "one million"}
, {10_000_000, "ten million"}
, {Integer.MAX_VALUE, "two billion one hundred forty seven million four hundred eighty three thousand six hundred forty seven"}
, {Integer.MIN_VALUE, "minus two billion one hundred forty seven million four hundred eighty three thousand six hundred forty eight"}
};
return Arrays.asList(data);
}
private int input;
private String expected;
public NumberToWordsConverterTest(int input, String expected) {
this.input = input;
this.expected = expected;
}
@Test
public void testConvert() {
assertThat(new NumberToWordsConverter().convert(input)
, is(equalTo(expected)));
}
}