2012-01-09 12 views

Respuesta

7

Lo que buscas se llama lexer. Un lexer divide la entrada en fragmentos (llamados tokens) que puede leer.

Afortunadamente, su lexer es bastante simple y se puede escribir a mano. Para lexers más complicados, puede usar flex (como en "The Fast Lexical Analyzer" - no Adobe Flex), o (dado que está usando Java) ANTLR (tenga en cuenta que ANTLR es mucho más que solo un lexer).

Simplemente cree una lista de expresiones regulares, una para cada token que coincida (tenga en cuenta que dado que su entrada es tan simple, probablemente pueda eliminar esta lista y combinarlas en una sola expresión regular. lexers más avanzados, ayuda a hacer una expresión regular para cada token), por ejemplo

\d+ 
\+ 
- 
* 
/
\(
\) 

A continuación, empezar un bucle: mientras que hay más personajes para ser analizados, ir a través de cada una de sus expresiones regulares e intentan hacer coincidir contra el principio de la cadena. Si coinciden, agregue el primer grupo coincidente a su lista de entrada. De lo contrario, continúe haciendo coincidir (si ninguno de ellos coincide, indique al usuario que tiene un error de sintaxis).

pseudocódigo:

List<String>input = new LinkedList<String>(); 
while(userInputString.length()>0){ 
    for (final Pattern p : myRegexes){ 
     final Matcher m = p.matcher(userInputString); 
     if(m.find()) { 
      input.add(m.group()); 
      //Remove the token we found from the user's input string so that we 
      //can match the rest of the string against our regular expressions. 
      userInputString=userInputString.substring(m.group().length()); 
      break; 
     } 
    } 
} 

Implementación notas:

  • Es posible que desee anteponer el carácter ^ a todas sus expresiones regulares. Esto asegura que anclas tus partidos contra el comienzo de la cuerda. Mi pseudocódigo supone que has hecho esto.
0

Esto podría ser un poco descuidado, porque todavía estoy aprendiendo, pero los divide en cuerdas.

TestClass public class {

public static void main(String[] args) 
{ 
    Scanner sc = new Scanner(System.in); 
    ArrayList<String> separatedInput = new ArrayList<String>(); 
    String input = ""; 

    System.out.print("Values: "); 
    input = sc.next(); 

    if (input.length() != 0) 
    { 
     boolean numberValue = true; 
     String numbers = ""; 

     for (int i = 0; i < input.length(); i++) 
     { 
      char ch = input.charAt(i); 
      String value = input.substring(i, i+1); 

      if (Character.isDigit(ch)) 
      { numberValue = true; numbers = numbers + value; } 

      if (!numberValue) 
      { separatedInput.add(numbers); separatedInput.add(value); numbers = ""; } 
      numberValue = false; 

      if (i == input.length() - 1) 
      { 
       if (Character.isDigit(ch)) 
       { separatedInput.add(numbers); } 
      } 
     } 

    } 
    System.out.println(separatedInput); 
} 

}

1

creo que el uso de pilas para dividir el operando y el operador y evaluar la expresión sería más apropiado. En la calculadora generalmente utilizamos Notación Infix para definir la expresión aritmética.

Operand1 op Operand2 

Comprobar la Shunting-yard algorithm utilizado en muchos de estos casos para analizar la expresión matemática. This es también una buena lectura.

Cuestiones relacionadas