1. 程式人生 > >字尾表示式的計算器Java實現

字尾表示式的計算器Java實現

直接上程式碼

package cn.john.cal;

/**
 * 
 * @ClassName: Operators
 * 
 * @Description: 操作符列舉
 * 
 * @author: John
 * 
 * @date: 2017年5月9日 下午22:05:16
 * 
 * 
 */
public enum OperatorsEnum {

    PLUS(0, '+'), MINUS(0, '-'), MULTIPLY(1, '*'), DIVIDE(1, '/'), MODULAR(1, '%'), LEFT_BRACKET(2,
            '('), RIGHT_BRACKET(2
, ')'); public Integer prior;// 優先順序 public Character operator;// 操作符 private OperatorsEnum(int prior, char operator) { this.prior = prior; this.operator = operator; } public String toString() { return String.valueOf(operator); } }
package cn.john.cal;

import
java.util.LinkedList; import java.util.Scanner; /** * * @ClassName: Cal * * @Description: * <p> * 基於字尾表示式的簡易計算器,目前支援個位數加、減、乘、除、模和括號六種運算。 * <p> * 中綴表示式->字尾表示式 操作符入棧 * <p> * 字尾表示式->計算值 運算元入棧 * * @author
: John * * @date: 2017年5月9日 下午7:55:58 * */
public class Cal { /** * @Title: toPostFix * @Description: 將中綴表示式轉換為字尾表示式 * @param infix * @return * @return: String */ public String toPostFix(String infix) { // 算式字元陣列 char[] ch = infix.trim().toCharArray(); LinkedList<OperatorsEnum> stack = new LinkedList<OperatorsEnum>(); StringBuilder sb = new StringBuilder(); OperatorsEnum op = null; for (int i = 0; i < ch.length; i++) { // 對每個算式字元,檢查它是不是操作符 if ((op = isOperator(ch[i])) == null) { sb.append(ch[i]); } else { // 右括號 // 持續彈出棧頂元素直到遇到左括號,但是不輸出左括號 if (op.equals(OperatorsEnum.RIGHT_BRACKET)) { // 如果不是左括號,持續彈出並輸出 while (!stack.peek().equals(OperatorsEnum.LEFT_BRACKET)) { sb.append(stack.pop()); } // 此時棧頂元素為左括號,直接彈出,不輸出 stack.pop(); } else { // 非右括號 // 1、彈出並輸出所有高優先順序或者同等優先順序,直到遇到低優先順序或者左括號為止 // 上面的彈出語句有可能將棧彈空,檢查stack的size避免NPE while (stack.size() > 0 && stack.peek().prior >= op.prior && !stack.peek().equals(OperatorsEnum.LEFT_BRACKET)) { sb.append(stack.pop()); } // 2、將當前操作符入棧 stack.push(op); } } } // 彈出所有棧中剩餘操作符 while (stack.size() > 0) { sb.append(stack.pop()); } return sb.toString(); } /** * @Title: calc * @Description: 計算字尾表示式的值 * @param postfix * @return * @return: double */ public double calc(String postfix) { char[] ch = postfix.toCharArray(); LinkedList<Double> stack = new LinkedList<Double>(); OperatorsEnum op = null; for (int i = 0; i < ch.length; i++) { if ((op = isOperator(ch[i])) == null) { // 不是操作符,將當前數值入棧 stack.push(Double.parseDouble(String.valueOf(ch[i]))); } else { // 是操作符,進行計算 double b = stack.pop(); double a = stack.pop(); switch (op) { case PLUS: stack.push(a + b); break; case MINUS: stack.push(a - b); break; case MULTIPLY: stack.push(a * b); break; case DIVIDE: stack.push(a / b); break; case MODULAR: stack.push(a % b); break; default: break; } } } return stack.pop(); } /** * @Title: isOperator * @Description: 判斷字元是否為操作符 * @param ch * @return * @return: OperatorsEnum */ private OperatorsEnum isOperator(char ch) { for (OperatorsEnum op : OperatorsEnum.values()) { if (ch == op.operator) { return op; } } return null; } // test /** * @Title: readEquation * @Description: 終端輸入算式 * @return * @return: String */ public String readEquation() { Scanner sc = new Scanner(System.in); String equation = sc.nextLine(); sc.close(); return equation; } public static void main(String[] args) { Cal c = new Cal(); System.out.println("Please input an equation,press ENTER to submit!"); String infix = c.readEquation(); String s = c.toPostFix(infix); System.out.println("postfix: " + s); System.out.println("Result: "+infix + "=" + c.calc(s)); } }