本程序实现了简单的加减乘除运算,可对小数、整数、负数实现运算。
本程序的算数运算使用栈实现,一个操作符栈和一个操作数栈。
本程序允许的操作符为+、-、*、/、英文左括号(“(”),英文右括号(“)”)。
JavaFX界面程序如下:
package collection;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import java.util.Stack;
public class EvaluateExpression extends Application {
private TextField expression = new TextField(); //表达式
private TextField result = new TextField(); //结果值
private Button evaluate = new Button("Evaluate"); //计算按钮
private Button clear = new Button("Clear"); //清除
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
GridPane gridPane = new GridPane(); //网格面板添加文本域对象
gridPane.setStyle("-fx-hgap: 5px; -fx-vgap: 5px; -fx-padding: 5px;");
gridPane.addRow(0, new Label("Enter an expression:"), expression);
gridPane.addRow(1, new Label("Result:"), result);
expression.setAlignment(Pos.BOTTOM_RIGHT); //文本域设置对齐
result.setAlignment(Pos.BOTTOM_RIGHT);
result.setEditable(false);
EventHandler<ActionEvent> eventHandler = event -> { //计算表达式处理器
try {
result.setText(format(evaluateExpression(expression.getText().trim())));
} catch (Exception ex) {
}
};
expression.setOnAction(eventHandler); //文本域、按钮注册处理器
evaluate.setOnAction(eventHandler);
clear.setOnAction(event -> {expression.setText(""); result.setText("");});
HBox hBox = new HBox(10, evaluate, clear); //水平面板添加按钮
hBox.setAlignment(Pos.CENTER);
BorderPane pane = new BorderPane(gridPane);
pane.setBottom(hBox);
Scene scene = new Scene(pane);
primaryStage.setScene(scene);
primaryStage.setTitle("EvaluateExpression");
primaryStage.show();
}
/** 计算表达式 */
public static double evaluateExpression(String expression) {
Stack<Double> operandStack = new Stack<>(); //操作数栈
Stack<Character> operatorStack = new Stack<>(); //操作符栈
expression = formatExpression(expression);
String[] tokens = expression.split(" "); //返回空格分隔数组
for (String token : tokens) { //遍历数组
switch (token) {
case "+":
case "-": //符号为+-
while (!operatorStack.isEmpty() &&
(operatorStack.peek() == '+' || operatorStack.peek() == '-' ||
operatorStack.peek() == '*' || operatorStack.peek() == '/'))
processAnOperator(operandStack, operatorStack);
operatorStack.push(token.charAt(0)); break;
case "*":
case "/": //符号为*/
while (!operatorStack.isEmpty() &&
(operatorStack.peek() == '*' ||
operatorStack.peek() == '/'))
processAnOperator(operandStack, operatorStack);
operatorStack.push(token.charAt(0)); break;
case "(": operatorStack.push('('); break;
case ")": //括号
while (operatorStack.peek() != '(')
processAnOperator(operandStack, operatorStack);
operatorStack.pop(); break;
default: operandStack.push(Double.parseDouble(token));
}
}
while (!operatorStack.isEmpty()) //处理剩余的操作符
processAnOperator(operandStack, operatorStack);
return operandStack.pop();
}
/** 处理一个操作符 */
public static void processAnOperator(Stack<Double> operandStack, Stack<Character> operatorStack) {
char op = operatorStack.pop();
double op1 = operandStack.pop();
double op2 = operandStack.pop();
switch (op) { //比较操作符,执行相应操作并入操作数栈
case '+': operandStack.push(op2 + op1); break;
case '-': operandStack.push(op2 - op1); break;
case '*': operandStack.push(op2 * op1); break;
case '/': operandStack.push(op2 / op1); break;
default:
}
}
/** 格式化表达式 */
public static String formatExpression(String s) {
StringBuilder stringBuilder = new StringBuilder();
s = s.replaceAll(" ", ""); //去除所有空格
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '(' || c == ')' || c == '+' || c == '*' || c == '/') //判断()+*/
stringBuilder.append(" ").append(c).append(" ");
else if (c == '.' || Character.isDigit(c)) //判断.和数字
stringBuilder.append(c);
else if (c == '-') { //判断-号
if (i == 0) stringBuilder.append(c); //负号
else if (s.charAt(i-1) == '+' || s.charAt(i-1) == '-' ||
s.charAt(i-1)== '*' || s.charAt(i-1) == '/' ||
s.charAt(i-1) == '(')
stringBuilder.append(c); //负号
else
stringBuilder.append(" ").append(c).append(" "); //减号
}
}
s = stringBuilder.toString().trim().replaceAll(" {2}", " ");
return s;
}
/** 格式化值 */
public static String format(double value) {
String v = String.valueOf(value);
return v.endsWith("0") ? String.valueOf((int)value) : v;
}
}