将String内的数学表达式计算为Float?

我需要用Java来评估数学表达式。

问题是,表达式是一个String对象。

有没有办法取字符串"( (21 + 3) / 4 )"并对其进行评估,以便它给出6作为结果?

到目前为止这是代码。

 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; class InfixApp { public static void main(String[] args) throws IOException { String input, output; while(true) { System.out.print("Enter infix: "); System.out.flush(); input = getString(); // read a string from kbd if( input.equals("") ) // quit if [Enter] break; // make a translator InToPost theTrans = new InToPost(input); output = theTrans.doTrans(); // do the translation System.out.println("Postfix is " + output + '\n'); } // end while } // end main() //-------------------------------------------------------------- public static String getString() throws IOException { InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); String s = br.readLine(); return s; } } // end class InfixApp 
 class InToPost // infix to postfix conversion { private StackX theStack; private String input; private String output = ""; //-------------------------------------------------------------- public InToPost(String in) // constructor { input = in; int stackSize = input.length(); theStack = new StackX(stackSize); } //-------------------------------------------------------------- public String doTrans() // do translation to postfix { for(int j=0; j<input.length(); j++) { char ch = input.charAt(j); theStack.displayStack("For "+ch+" "); // *diagnostic* switch(ch) { case '+': // its + or - case '-': gotOper(ch, 1); // go pop operators break; // (precedence 1) case '*': // its * or / or $ case '/': case '$': gotOper(ch, 2); // go pop operators break; // (precedence 2) case '(': // its a left paren theStack.push(ch); // push it break; case ')': // its a right paren gotParen(ch); // go pop operators break; default: // must be an operand output = output + ch ; // write it to output break; }// end switch } // end for while( !theStack.isEmpty() ) // pop remaining opers { theStack.displayStack("While "); // *diagnostic* output += theStack.pop() + " "; // write to output } theStack.displayStack("End "); // *diagnostic* return output; // return postfix } // end doTrans() //-------------------------------------------------------------- public void gotOper(char opThis, int prec1) { // got operator from input while( !theStack.isEmpty() ) { char opTop = theStack.pop(); if( opTop == '(' ) // if its a ( { theStack.push(opTop); // restore ( break; } else // its an operator { int prec2; // precedence of new op if(opTop== '+' || opTop == '-' ) // find new op prec prec2 = 1; else prec2 = 2; if(prec2 < prec1) // if prec of new op less { // than prec of old theStack.push(opTop); // save newly-popped op break; } else // prec of new not less output = output + opTop; // than prec of old } // end else (its an operator) } // end while theStack.push(opThis); // push new operator } // end gotOp() //-------------------------------------------------------------- public void gotParen(char ch) { // got right paren from input while( !theStack.isEmpty() ) { char chx = theStack.pop(); if( chx == '(' ) // if popped ( break; // were done else // if popped operator output = output + chx; // output it } // end while } // end popOps() //-------------------------------------------------------------- } // end class InToPost 
 import java.io.*; // for I/O class StackX { private int maxSize; private char[] stackArray; private int top; //-------------------------------------------------------------- public StackX(int s) // constructor { maxSize = s; stackArray = new char[maxSize]; top = -1; } //-------------------------------------------------------------- public void push(char j) // put item on top of stack { stackArray[++top] = j; } //-------------------------------------------------------------- public char pop() // take item from top of stack { return stackArray[top--]; } //-------------------------------------------------------------- public char peek() // peek at top of stack { return stackArray[top]; } //-------------------------------------------------------------- public boolean isEmpty() // true if stack is empty { return (top == -1); } //------------------------------------------------------------- public int size() // return size { return top+1; } //-------------------------------------------------------------- public char peekN(int n) // return item at index n { return stackArray[n]; } //-------------------------------------------------------------- public void displayStack(String s) { System.out.print(s); System.out.print("Stack (bottom-->top): "); for(int j=0; j<size(); j++) { System.out.print( peekN(j) ); System.out.print(" "); } System.out.println(" "); } } // end class StackX 

您可以使用ScriptEngine:

 ScriptEngineManager mgr = new ScriptEngineManager(); ScriptEngine engine = mgr.getEngineByName("JavaScript"); String foo = "( (21 + 3) / 4 ) "; try { System.out.println(engine.eval(foo)); } catch (ScriptException e) { // TODO Auto-generated catch block e.printStackTrace(); } 

免责声明:这个答案只有在你打算自己做的时候才有效。 如果您正在寻找一种快速/有效的方法来进行这种解析,那么使用其他答案中提出的工具/库当然会更好…

您有一个程序将中缀表示法转换为后缀表示法。 例如:

中缀: ((21 + 3)/ 4)

应输出如下内容:

后缀: 21 3 + 4 /

现在,如果你想评估这个表达式,后缀表示法很简单:当从左到右读取标记时,你只需要堆叠操作数(21,3,…)直到操作符(+,/)为找到。 然后弹出堆栈,应用运算符并堆叠结果。

  • 在里面
    • stack: [] ,expr: 21 3 + 4 /
  • 阅读21 ,堆叠它:
    • 堆栈: [21] ,expr: 3 + 4 /
  • 阅读3 ,堆叠它:
    • 堆栈: [21 3] ,expr: + 4 /
  • 读取+ ,弹出321 ,添加并堆叠结果24
    • 堆栈: [24] ,expr: 4 /
  • 阅读4 ,堆叠它
    • stack: [24 4] ,expr: /
  • read / ,pop 424 ,divide and stack result 6
    • stack: [6] ,expr : .

当没有更多令牌要读取时,堆栈包含最终结果。