Как преобразовать слова в число?
Я хочу преобразовать слова, содержащие буквы алфавита, в репрезентативное число в Java.
Например, four hundred four
следует оценить по количеству 404
,
Если буквы как бред asdf
тогда это ошибка.
Я знаю, что могу конвертировать голые символы в их целочисленные, эквивалентные ascii, добавляя их вместе, но я хочу, чтобы извлекались только цифры за английскими словосочетаниями.
3 ответа
Вот код, который я придумал, пытаясь решить ту же проблему. Имейте в виду, что я не профессионал и не обладаю безумным опытом. Это не медленно, но я уверен, что это может быть быстрее / чище / и т.д. Я использовал его для преобразования голосовых слов в числа для расчета в моем собственном "Джарвисе", как "Железный человек". Он может обрабатывать числа менее 1 миллиарда, хотя его можно легко расширить, включив гораздо более высокие величины за счет очень небольшого времени.
public static final String[] DIGITS = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
public static final String[] TENS = {null, "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};
public static final String[] TEENS = {"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"};
public static final String[] MAGNITUDES = {"hundred", "thousand", "million", "point"};
public static final String[] ZERO = {"zero", "oh"};
public static String replaceNumbers (String input) {
String result = "";
String[] decimal = input.split(MAGNITUDES[3]);
String[] millions = decimal[0].split(MAGNITUDES[2]);
for (int i = 0; i < millions.length; i++) {
String[] thousands = millions[i].split(MAGNITUDES[1]);
for (int j = 0; j < thousands.length; j++) {
int[] triplet = {0, 0, 0};
StringTokenizer set = new StringTokenizer(thousands[j]);
if (set.countTokens() == 1) { //If there is only one token given in triplet
String uno = set.nextToken();
triplet[0] = 0;
for (int k = 0; k < DIGITS.length; k++) {
if (uno.equals(DIGITS[k])) {
triplet[1] = 0;
triplet[2] = k + 1;
}
if (uno.equals(TENS[k])) {
triplet[1] = k + 1;
triplet[2] = 0;
}
}
}
else if (set.countTokens() == 2) { //If there are two tokens given in triplet
String uno = set.nextToken();
String dos = set.nextToken();
if (dos.equals(MAGNITUDES[0])) { //If one of the two tokens is "hundred"
for (int k = 0; k < DIGITS.length; k++) {
if (uno.equals(DIGITS[k])) {
triplet[0] = k + 1;
triplet[1] = 0;
triplet[2] = 0;
}
}
}
else {
triplet[0] = 0;
for (int k = 0; k < DIGITS.length; k++) {
if (uno.equals(TENS[k])) {
triplet[1] = k + 1;
}
if (dos.equals(DIGITS[k])) {
triplet[2] = k + 1;
}
}
}
}
else if (set.countTokens() == 3) { //If there are three tokens given in triplet
String uno = set.nextToken();
String dos = set.nextToken();
String tres = set.nextToken();
for (int k = 0; k < DIGITS.length; k++) {
if (uno.equals(DIGITS[k])) {
triplet[0] = k + 1;
}
if (tres.equals(DIGITS[k])) {
triplet[1] = 0;
triplet[2] = k + 1;
}
if (tres.equals(TENS[k])) {
triplet[1] = k + 1;
triplet[2] = 0;
}
}
}
else if (set.countTokens() == 4) { //If there are four tokens given in triplet
String uno = set.nextToken();
String dos = set.nextToken();
String tres = set.nextToken();
String cuatro = set.nextToken();
for (int k = 0; k < DIGITS.length; k++) {
if (uno.equals(DIGITS[k])) {
triplet[0] = k + 1;
}
if (cuatro.equals(DIGITS[k])) {
triplet[2] = k + 1;
}
if (tres.equals(TENS[k])) {
triplet[1] = k + 1;
}
}
}
else {
triplet[0] = 0;
triplet[1] = 0;
triplet[2] = 0;
}
result = result + Integer.toString(triplet[0]) + Integer.toString(triplet[1]) + Integer.toString(triplet[2]);
}
}
if (decimal.length > 1) { //The number is a decimal
StringTokenizer decimalDigits = new StringTokenizer(decimal[1]);
result = result + ".";
System.out.println(decimalDigits.countTokens() + " decimal digits");
while (decimalDigits.hasMoreTokens()) {
String w = decimalDigits.nextToken();
System.out.println(w);
if (w.equals(ZERO[0]) || w.equals(ZERO[1])) {
result = result + "0";
}
for (int j = 0; j < DIGITS.length; j++) {
if (w.equals(DIGITS[j])) {
result = result + Integer.toString(j + 1);
}
}
}
}
return result;
}
Ввод должен быть в грамматически правильном синтаксисе, в противном случае он будет иметь проблемы (создайте функцию для удаления "и"). Строковый ввод "двести два миллиона пятьдесят три тысячи точка ноль восемь пять восемь о два" возвращает:
two hundred two million fifty three thousand point zero eight five eight oh two
202053000.085802
It took 2 milliseconds.
Основная стратегия будет иметь value
переменная, с которой вы работаете. Каждый раз, когда вы видите строку "один", "два", "одиннадцать", "семьдесят", вы добавляете эту сумму к value
, Когда вы видите строку типа "сто", "тысяча", "миллион", вы умножаете value
на эту сумму.
Для больших чисел вам, вероятно, потребуется создать несколько промежуточных итогов и объединить их в конце. Шаги для обработки числа, подобного 111 374, записанного как "сто одиннадцать тысяч триста семьдесят четыре", будут
- "один" ->
value[0] += 1
(сейчас1
) - "сто" ->
value[0] *= 100
(сейчас100
) - "одиннадцать" ->
value[0] += 11
(сейчас111
) - "тысяча" ->
value[0] *= 1000
(сейчас111000
) - "три" ->
value[1] += 3
- "сто" ->
value[1] *= 100
(сейчас300
) - "семьдесят" ->
value[1] += 70
(сейчас370
) - "четверка" ->
value[1] += 4
сейчас (374)
Вам все еще нужно выяснить, как решить, когда строить его как несколько значений. Похоже, вы должны начать новый промежуточный итог, когда вы столкнетесь с множителем ("сотня"), который меньше, чем самый последний увиденный множитель.
public class InNumerals5Digits {
static String testcase1 = "ninety nine thousand nine hundred ninety nine";//
public static void main(String args[]){
InNumerals5Digits testInstance = new InNumerals5Digits();
int result = testInstance.inNumerals(testcase1);
System.out.println("Result : "+result);
}
//write your code here
public int inNumerals(String inwords)
{
int wordnum = 0;
String[] arrinwords = inwords.split(" ");
int arrinwordsLength = arrinwords.length;
if(inwords.equals("zero"))
{
return 0;
}
if(inwords.contains("thousand"))
{
int indexofthousand = inwords.indexOf("thousand");
//System.out.println(indexofthousand);
String beforethousand = inwords.substring(0,indexofthousand);
//System.out.println(beforethousand);
String[] arrbeforethousand = beforethousand.split(" ");
int arrbeforethousandLength = arrbeforethousand.length;
//System.out.println(arrbeforethousandLength);
if(arrbeforethousandLength==2)
{
wordnum = wordnum + 1000*(wordtonum(arrbeforethousand[0]) + wordtonum(arrbeforethousand[1]));
//System.out.println(wordnum);
}
if(arrbeforethousandLength==1)
{
wordnum = wordnum + 1000*(wordtonum(arrbeforethousand[0]));
//System.out.println(wordnum);
}
}
if(inwords.contains("hundred"))
{
int indexofhundred = inwords.indexOf("hundred");
//System.out.println(indexofhundred);
String beforehundred = inwords.substring(0,indexofhundred);
//System.out.println(beforehundred);
String[] arrbeforehundred = beforehundred.split(" ");
int arrbeforehundredLength = arrbeforehundred.length;
wordnum = wordnum + 100*(wordtonum(arrbeforehundred[arrbeforehundredLength-1]));
String afterhundred = inwords.substring(indexofhundred+8);//7 for 7 char of hundred and 1 space
//System.out.println(afterhundred);
String[] arrafterhundred = afterhundred.split(" ");
int arrafterhundredLength = arrafterhundred.length;
if(arrafterhundredLength==1)
{
wordnum = wordnum + (wordtonum(arrafterhundred[0]));
}
if(arrafterhundredLength==2)
{
wordnum = wordnum + (wordtonum(arrafterhundred[1]) + wordtonum(arrafterhundred[0]));
}
//System.out.println(wordnum);
}
if(!inwords.contains("thousand") && !inwords.contains("hundred"))
{
if(arrinwordsLength==1)
{
wordnum = wordnum + (wordtonum(arrinwords[0]));
}
if(arrinwordsLength==2)
{
wordnum = wordnum + (wordtonum(arrinwords[1]) + wordtonum(arrinwords[0]));
}
//System.out.println(wordnum);
}
return wordnum;
}
public int wordtonum(String word)
{
int num = 0;
switch (word) {
case "one": num = 1;
break;
case "two": num = 2;
break;
case "three": num = 3;
break;
case "four": num = 4;
break;
case "five": num = 5;
break;
case "six": num = 6;
break;
case "seven": num = 7;
break;
case "eight": num = 8;
break;
case "nine": num = 9;
break;
case "ten": num = 10;
break;
case "eleven": num = 11;
break;
case "twelve": num = 12;
break;
case "thirteen": num = 13;
break;
case "fourteen": num = 14;
break;
case "fifteen": num = 15;
break;
case "sixteen": num = 16;
break;
case "seventeen": num = 17;
break;
case "eighteen": num = 18;
break;
case "nineteen": num = 19;
break;
case "twenty": num = 20;
break;
case "thirty": num = 30;
break;
case "forty": num = 40;
break;
case "fifty": num = 50;
break;
case "sixty": num = 60;
break;
case "seventy": num = 70;
break;
case"eighty": num = 80;
break;
case "ninety": num = 90;
break;
case "hundred": num = 100;
break;
case "thousand": num = 1000;
break;
/*default: num = "Invalid month";
break;*/
}
return num;
}
}