将字符串中的数学表达式计算为浮点数?
Evaluate a math expression inside a String into a 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
您可以使用脚本引擎:
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();
}
免责声明:此答案仅在您打算自己做这些事情时才有效。如果您正在寻找一种 quick/efficient 方法来进行这种解析,那么使用其他答案中建议的 tool/library 肯定会更好...
您有一个将中缀表示法转换为后缀表示法的程序。例如:
infix: ( ( 21 + 3 ) / 4 )
应该输出如下内容:
postfix: 21 3 + 4 /
现在如果你想计算这个表达式,后缀表示法非常简单:当从左到右读取令牌时,你只需要堆叠操作数 (21, 3, ...) 直到运算符 ( +, /) 被发现。然后弹出堆栈,应用运算符并堆栈结果。
- 初始化
- 堆栈:[],表达式:21 3 + 4 /
- 阅读
21
,堆叠它:
- 堆栈:[21],表达式:3 + 4 /
- 阅读
3
,堆叠它:
- 堆栈:[21 3],表达式:+ 4 /
- 读取
+
,弹出3
和21
,添加并堆叠结果24
- 堆栈:[24],表达式:4 /
- 阅读
4
,堆叠它
- 堆栈:[24 4],表达式:/
- 读取
/
,弹出4
和24
,除法叠加结果6
- 堆栈:[6],表达式:.
当没有更多的令牌可读时,堆栈包含最终结果。
我需要计算 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
您可以使用脚本引擎:
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();
}
免责声明:此答案仅在您打算自己做这些事情时才有效。如果您正在寻找一种 quick/efficient 方法来进行这种解析,那么使用其他答案中建议的 tool/library 肯定会更好...
您有一个将中缀表示法转换为后缀表示法的程序。例如:
infix: ( ( 21 + 3 ) / 4 )
应该输出如下内容:
postfix: 21 3 + 4 /
现在如果你想计算这个表达式,后缀表示法非常简单:当从左到右读取令牌时,你只需要堆叠操作数 (21, 3, ...) 直到运算符 ( +, /) 被发现。然后弹出堆栈,应用运算符并堆栈结果。
- 初始化
- 堆栈:[],表达式:21 3 + 4 /
- 阅读
21
,堆叠它:- 堆栈:[21],表达式:3 + 4 /
- 阅读
3
,堆叠它:- 堆栈:[21 3],表达式:+ 4 /
- 读取
+
,弹出3
和21
,添加并堆叠结果24
- 堆栈:[24],表达式:4 /
- 阅读
4
,堆叠它- 堆栈:[24 4],表达式:/
- 读取
/
,弹出4
和24
,除法叠加结果6
- 堆栈:[6],表达式:.
当没有更多的令牌可读时,堆栈包含最终结果。