Skip to content

Instantly share code, notes, and snippets.

@alzaichsank
Last active August 23, 2019 17:16
Show Gist options
  • Save alzaichsank/e9611cd01fc38aba28f2ecc0a8dae68c to your computer and use it in GitHub Desktop.
Save alzaichsank/e9611cd01fc38aba28f2ecc0a8dae68c to your computer and use it in GitHub Desktop.
Convertion word to number with input [English version]
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
/**
*
* @author alzaichsank
*/
public class ConvertionWordToNumber {
final static List<String> allowedStrings = Arrays.asList("and", "zero", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen",
"seventeen", "eighteen", "nineteen", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty",
"ninety", "hundred", "thousand", "million", "billion", "trillion");
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Masukan Huruf yang akan disebut: ");
System.out.println(new ConvertionWordToNumber().doConvert(sc.nextLine()));
}
public static String doConvert(String Huruf){
String words = convertTextualNumbersInDocument(Huruf);
return words;
}
public static String convertTextualNumbersInDocument(String inputText) {
// splits text into words and deals with hyphenated numbers. Use linked
// list due to manipulation during processing
List<String> words = new LinkedList<String>(cleanAndTokenizeText(inputText));
// replace all the textual numbers
words = replaceTextualNumbers(words);
// put spaces back in and return the string. Should be the same as input
// text except from textual numbers
return wordListToString(words);
}
/**
* Does the replacement of textual numbers, processing each word at a time
* and grouping them before doing the conversion
*
* @param words
* @return
*/
private static List<String> replaceTextualNumbers(List<String> words) {
// holds each group of textual numbers being processed together. e.g.
// "one" or "five hundred and two"
List<String> processingList = new LinkedList<String>();
int i = 0;
while (i < words.size() || !processingList.isEmpty()) {
// caters for sentences only containing one word (that is a number)
String word = "";
if (i < words.size()) {
word = words.get(i);
}
// strip word of all punctuation to make it easier to process
String wordStripped = word.replaceAll("[^a-zA-Z\\s]", "").toLowerCase();
// 2nd condition: skip "and" words by themselves and at start of num
if (allowedStrings.contains(wordStripped) && !(processingList.size() == 0 && wordStripped.equals("and"))) {
words.remove(i); // remove from main list, will process later
processingList.add(word);
} else if (processingList.size() > 0) {
// found end of group of textual words to process
//if "and" is the last word, add it back in to original list
String lastProcessedWord = processingList.get(processingList.size() - 1);
if (lastProcessedWord.equals("and")) {
words.add(i, "and");
processingList.remove(processingList.size() - 1);
}
// main logic here, does the actual conversion
String wordAsDigits = String.valueOf(convertWordsToNum(processingList));
wordAsDigits = retainPunctuation(processingList, wordAsDigits);
words.add(i, String.valueOf(wordAsDigits));
processingList.clear();
i += 2;
} else {
i++;
}
}
return words;
}
/**
* Retain punctuation at the start and end of a textual number.
*
* e.g. (seventy two) -> (72)
*
* @param processingList
* @param wordAsDigits
* @return
*/
private static String retainPunctuation(List<String> processingList, String wordAsDigits) {
String lastWord = processingList.get(processingList.size() - 1);
char lastChar = lastWord.trim().charAt(lastWord.length() - 1);
if (!Character.isLetter(lastChar)) {
wordAsDigits += lastChar;
}
String firstWord = processingList.get(0);
char firstChar = firstWord.trim().charAt(0);
if (!Character.isLetter(firstChar)) {
wordAsDigits = firstChar + wordAsDigits;
}
return wordAsDigits;
}
/**
* Splits up hyphenated textual words. e.g. twenty-two -> twenty two
*
* @param sentence
* @return
*/
private static List<String> cleanAndTokenizeText(String sentence) {
List<String> words = new LinkedList<String>(Arrays.asList(sentence.split(" ")));
// remove hyphenated textual numbers
for (int i = 0; i < words.size(); i++) {
String str = words.get(i);
if (str.contains("-")) {
List<String> splitWords = Arrays.asList(str.split("-"));
// just check the first word is a textual number. Caters for
// "twenty-five," without having to strip the comma
if (splitWords.size() > 1 && allowedStrings.contains(splitWords.get(0))) {
words.remove(i);
words.addAll(i, splitWords);
}
}
}
return words;
}
/**
* Creates string including spaces from a list of words
*
* @param list
* @return
*/
private static String wordListToString(List<String> list) {
StringBuilder result = new StringBuilder("");
for (int i = 0; i < list.size(); i++) {
String str = list.get(i);
if (i == 0 && str != null) {
result.append(list.get(i));
} else if (str != null) {
result.append(" " + list.get(i));
}
}
return result.toString();
}
/**
* Logic for taking a textual number string and converting it into a number
* e.g. twenty five -> 25
*
* This relies on there only being one textual number being processed. Steps
* prior to this deal with breaking a paragraph down into individual textual
* numbers, which could consist of a number of words.
*
* @param input
* @return
*/
private static long convertWordsToNum(List<String> words) {
long finalResult = 0;
long intermediateResult = 0;
for (String str : words) {
// clean up string for easier processing
str = str.toLowerCase().replaceAll("[^a-zA-Z\\s]", "");
if (str.equalsIgnoreCase("zero")) {
intermediateResult += 0;
} else if (str.equalsIgnoreCase("one")) {
intermediateResult += 1;
} else if (str.equalsIgnoreCase("two")) {
intermediateResult += 2;
} else if (str.equalsIgnoreCase("three")) {
intermediateResult += 3;
} else if (str.equalsIgnoreCase("four")) {
intermediateResult += 4;
} else if (str.equalsIgnoreCase("five")) {
intermediateResult += 5;
} else if (str.equalsIgnoreCase("six")) {
intermediateResult += 6;
} else if (str.equalsIgnoreCase("seven")) {
intermediateResult += 7;
} else if (str.equalsIgnoreCase("eight")) {
intermediateResult += 8;
} else if (str.equalsIgnoreCase("nine")) {
intermediateResult += 9;
} else if (str.equalsIgnoreCase("ten")) {
intermediateResult += 10;
} else if (str.equalsIgnoreCase("eleven")) {
intermediateResult += 11;
} else if (str.equalsIgnoreCase("twelve")) {
intermediateResult += 12;
} else if (str.equalsIgnoreCase("thirteen")) {
intermediateResult += 13;
} else if (str.equalsIgnoreCase("fourteen")) {
intermediateResult += 14;
} else if (str.equalsIgnoreCase("fifteen")) {
intermediateResult += 15;
} else if (str.equalsIgnoreCase("sixteen")) {
intermediateResult += 16;
} else if (str.equalsIgnoreCase("seventeen")) {
intermediateResult += 17;
} else if (str.equalsIgnoreCase("eighteen")) {
intermediateResult += 18;
} else if (str.equalsIgnoreCase("nineteen")) {
intermediateResult += 19;
} else if (str.equalsIgnoreCase("twenty")) {
intermediateResult += 20;
} else if (str.equalsIgnoreCase("thirty")) {
intermediateResult += 30;
} else if (str.equalsIgnoreCase("forty")) {
intermediateResult += 40;
} else if (str.equalsIgnoreCase("fifty")) {
intermediateResult += 50;
} else if (str.equalsIgnoreCase("sixty")) {
intermediateResult += 60;
} else if (str.equalsIgnoreCase("seventy")) {
intermediateResult += 70;
} else if (str.equalsIgnoreCase("eighty")) {
intermediateResult += 80;
} else if (str.equalsIgnoreCase("ninety")) {
intermediateResult += 90;
} else if (str.equalsIgnoreCase("hundred")) {
intermediateResult *= 100;
} else if (str.equalsIgnoreCase("thousand")) {
intermediateResult *= 1000;
finalResult += intermediateResult;
intermediateResult = 0;
} else if (str.equalsIgnoreCase("million")) {
intermediateResult *= 1000000;
finalResult += intermediateResult;
intermediateResult = 0;
} else if (str.equalsIgnoreCase("billion")) {
intermediateResult *= 1000000000;
finalResult += intermediateResult;
intermediateResult = 0;
} else if (str.equalsIgnoreCase("trillion")) {
intermediateResult *= 1000000000000L;
finalResult += intermediateResult;
intermediateResult = 0;
}
}
finalResult += intermediateResult;
intermediateResult = 0;
return finalResult;
}
}
@alzaichsank
Copy link
Author

alzaichsank commented Aug 23, 2019

refrence by jgraham0325 :
jgraham0325/WordsToNumbersUtil.java

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment