如何查找String的下一个标记

时间:2013-10-29 16:41:35

标签: java math postfix-notation infix-notation

我正在研究一种解决算术方程的程序。

等式的一个例子是:

4+(5/4)+3/((5/3-2.4(*(5-7))

我有一个程序可以将这个等式从中缀转换为后缀形式,但该程序正在弄乱2.4中的小数。

将2和4视为单独的数字,它们应被视为一个数字。我该如何解决这个问题?

import java.util.EmptyStackException;
import java.util.Scanner;
import myUtil.*;

public class InfixToPostfix extends Asg6
{
   public static class SyntaxErrorException extends Exception
   {
      SyntaxErrorException(String message)
      {
         super(message);
      }
   }
   private AStack<Character> operatorStack;
   private static final String operators = "+-*/^()";
   private static final int[] precedence =
   {
      1, 1, 2, 2, 3, -1, -1
   };
   private StringBuilder postfix;

   public String convert(String infix) throws SyntaxErrorException
   {
      operatorStack = new AStack<Character>();
      postfix = new StringBuilder();

      try
      {
         String nextToken;
         Scanner scan = new Scanner(infix);
         while ((nextToken = scan.findInLine("[\\p{L}\\p{N}]+|[-+/\\*^()]")) != null)
         {
            char firstChar = nextToken.charAt(0);
            if (Character.isJavaIdentifierStart(firstChar) || Character.isDigit(firstChar))
            {
               postfix.append(nextToken);
               postfix.append(' ');
            }
            else if (isOperator(firstChar))
            {
               processOperator(firstChar);
            }
            else
            {
               throw new SyntaxErrorException("Unexpected Character: " + firstChar);
            }
         }
         while (!operatorStack.empty())
         {
            char op = operatorStack.pop();
            if (op == '(')
            {
               throw new SyntaxErrorException("Unmatched parenthesis");
            }
            postfix.append(op);
            postfix.append(' ');
         }
         return postfix.toString();
      }
      catch (EmptyStackException ex)
      {
         throw new SyntaxErrorException("Syntax Error: The stack is empty");
      }
   }

   private void processOperator(char op)
   {
      if (operatorStack.empty() || op == '(')
      {
         operatorStack.push(op);
      }
      else
      {
         char topOp = operatorStack.peek();
         if (precedence(op) > precedence(topOp))
         {
            operatorStack.push(op);
         }
         else
         {
            while (!operatorStack.empty() && precedence(op) <= precedence(topOp))
            {
               operatorStack.pop();
               if (topOp == '(')
               {
                  break;
               }
               postfix.append(topOp);
               postfix.append(' ');
               if (!operatorStack.empty())
               {
                  topOp = operatorStack.peek();
               }
            }
            if (op != ')')
            {
               operatorStack.push(op);
            }
         }
      }
   }

   private boolean isOperator(char ch)
   {
      return operators.indexOf(ch) != -1;
   }

   private int precedence(char op)
   {
      return precedence[operators.indexOf(op)];
   }
}

1 个答案:

答案 0 :(得分:3)

此:

while((nextToken = scan.findInLine("[\\p{L}\\p{N}]+|[-+/\\*^()]")) != null)

将匹配一串字母或一串数字字符或其中一个标点字符;但显然你想要比简单的数字字符串更复杂的东西。以下内容还将匹配一个包含1个或多个数字字符的字符串,后跟一个点,后跟另一个包含1个或多个数字字符的字符串:

while((nextToken = scan.findInLine("\\p{L}+|\\p{N}+(\\.\\p{N}+)?|[-+/\\*^()]")) != null)

括号中的部分匹配一个点和一个或多个数字;组之后的?表示如果找到其中一个或者如果没有找到匹配(即子模式的0或1次出现)。