2010-10-31 3 views
18

Я хочу преобразовать слова, содержащие алфавитные символы, в представительское число в Java.Как преобразовать слова в число?

Например, four hundred four следует оценить цифру 404.

Если буквы тарабарщины, такие как asdf, то это ошибка.

Я знаю, что могу convert bare Characters to their ascii equivalent Integer, добавляя их вместе, но мне нужны только цифры за английскими фразами.

+1

Как насчет «четыреста четыре»? –

+0

да это тоже разрешено – mimi

+0

Это очень сложная задача, когда вы рассматриваете все возможности. Английский позволяет много разных способов говорить одно и то же, даже с числами. Возможно, вам лучше составить список правил, которые вы ожидаете? –

ответ

11

Основная стратегия - иметь переменную 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)

Вы будете по-прежнему необходимо выяснить, как решить, когда его построить как несколько значений. Похоже, вы должны начать новый промежуточный итог, когда встретите множитель («сотню»), который равен меньше, чем самый последний увиденный множитель.

+0

Возможно, вы захотите поместить все слова в строку' szWords [] '. Итак, 'szWords [0] =« сто тысяч »,' szWords [1] = «одиннадцать сотен тысяч», 'szWords [2] =« три сотни »,' szWords [3] = «семьдесят» ' , 'szWords [4] =" four "' –

+0

@muntoo - непонятно, что должно делать ваше предложение –

13

Вот какой-то код, который я придумал при попытке решить ту же проблему. Имейте в виду, что я не профессионал и не имею безумного опыта. Это не медленно, но я уверен, что это может быть быстрее/чище/и т. Д. Я использовал его для преобразования распознанных слов в числа для вычисления в моем собственном «Jarvis» a la Iron Man. Он может обрабатывать цифры менее 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. 
+2

Спасибо, этот ответ - большой таймер экономии! Однако поле TEENS никогда не используется - это не будет распознавать строки типа «одиннадцать». Это легко исправить - например, в первом, если блок добавит , если (uno.equals (TENS [k])) триплет [2] = k + 10; – smihael

+0

@smihael вы хотите добавить: 'if (uno.equals (TEENS [k])) триплет [2] = k + 10;' (с 'TEENS', а не' TENS')? – MattClimbs

4
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; 
    } 
} 
Смежные вопросы