2010-10-31 10 views
18

Quiero convertir palabras que contienen caracteres alfabéticos en un número representativo en Java. Por ejemplo, four hundred four debe evaluar al número 404.¿Cómo convertir palabras a un número?

Si las letras son un galimatías como asdf, entonces eso es un error.

Sé que puedo convert bare Characters to their ascii equivalent Integer, anexándolos, pero solo quiero los números detrás de las palabras en inglés extraídas.

+1

¿Qué hay de "¡Cuatrocientas cuatro"? –

+0

sí, este también es permitido – mimi

+0

. Es una tarea muy difícil cuando se consideran todas las posibilidades. El inglés permite muchas formas de decir lo mismo, incluso con números. ¿Será mejor que elabores una lista de reglas que esperas? –

Respuesta

11

La estrategia básica sería tener una variable value con la que trabaje. Cada vez que vea una cadena "uno", "dos", "once", "setenta", agregará esa cantidad a value. Cuando vea una cadena como "cien", "mil", "millón", podría multiplicarvalue por esa cantidad.

Para números más grandes, es probable que necesite crear algunos subtotales y combinarlos al final. Los pasos para procesar un número como 111.374 escrita como "cien las once de mil de tres cientos setenta y cuatro" habría

  • "uno" ->value[0] += 1 (ahora 1)
  • "cientos" ->value[0] *= 100 (ahora 100)
  • "once" ->value[0] += 11 (ahora 111)
  • "mil" ->value[0] *= 1000 (ahora 111000)
  • "tres" ->value[1] += 3
  • "cientos" ->value[1] *= 100 (ahora 300)
  • "setenta" ->value[1] += 70 (ahora 370)
  • "cuatro" ->value[1] += 4 ahora (374)

usted todavía necesidad de averiguar cómo decidir cuándo construirlo como valores múltiples. Parece que debe comenzar un subtotal nuevo cuando encuentre un multiplicador ("cien") que es más pequeño que el multiplicador visto más recientemente.

+0

Es posible que desee poner todas las palabras en una 'cadena szWords []'. Entonces, 'szWords [0] =" cien thousand "', 'szWords [1] =" once hundred thousand "', 'szWords [2] =" trescientos "', 'szWords [3] =" setenta "' , 'szWords [4] =" four "' –

+0

@muntoo - no está claro lo que su sugerencia se supone que debe lograr –

13

Este es un código que surgió cuando intentaba resolver el mismo problema. Tenga en cuenta que no soy un profesional y no tengo una gran cantidad de experiencia. No es lento, pero estoy seguro de que podría ser más rápido/limpiador/etc. Lo usé para convertir palabras reconocidas por voz en números para el cálculo en mi propio "Jarvis" a la Iron Man. Puede manejar números menores de mil millones, aunque podría expandirse fácilmente para incluir magnitudes mucho más altas a un costo de muy poco tiempo.

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; 
} 

entrada debe estar en la sintaxis gramatical correcta, de lo contrario tendrá problemas (crear una función para eliminar "y"). Una entrada de cadena de "Dos de dos millones de centenar de cincuenta por mil de tres punto cero ocho cinco ocho oh dos" devuelve:

two hundred two million fifty three thousand point zero eight five eight oh two 
202053000.085802 
It took 2 milliseconds. 
+2

¡Gracias, esta respuesta es un excelente temporizador para guardar! Sin embargo, el campo ADOLESCENTES nunca se usa; esto no reconocerá cadenas como "once". Esto es fácil de arreglar, por ejemplo, en el primer bloque si agrega if (uno.equals (TENS [k])) triplete [2] = k + 10; – smihael

+0

@smihael ¿Quiere agregar: 'if (uno.equals (TEENS [k])) triplete [2] = k + 10;' (con 'TEENS' en lugar de' 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; 
    } 
} 
Cuestiones relacionadas