前言:
计算器的模拟实现主要分模式匹配和式子解析两部分,本文主要针对后者进行分析并实现。
测试样例:
1+2
3 * (4 + 5)
(4 + 5) / 3 + (1 + 2*1)
预计输出:
1+2 ==> 3
3 * (4 + 5) ==> 27
(4 + 5) / 3 + (1 + 2*1) ==> 6
分以下3个步骤:
1)StringTokenizer切分单个字符;
2)根据计算的优先级,通过当前运算符判断是否进行运算操作;
(括号 > 乘除 > 加减)
3)两栈进行数字运算;
附Java代码:
package com.yeezhao.common.elt; import java.util.Stack; import java.util.StringTokenizer; /** * 正整数计算器 * * @author Administrator -> junhong * @since 2016年12月13日 下午1:22:40 */ public class CaculatorSimulate { private Stack<Character> operator = new Stack<>(); // 操作符 private Stack<Integer> operand = new Stack<>(); // 操作数 0-9 public void testCaculate() { } public void testOutput() { } /** * 返回计算结果 * * @param exp * 正整数的加减乘除表达式 * @return */ public Integer caculate(String exp) { if (exp == null || exp.isEmpty()) { System.out.println("invalid exp!"); return 0; } StringTokenizer arr = new StringTokenizer(exp, "+-/*()", true); while (arr.hasMoreTokens()) { String text = arr.nextToken().trim(); if (text.length() == 0) { // fix '((' continue; } char c = text.charAt(0); if (c == '+' || c == '-') { while (!operator.isEmpty() && ((operator.peek() == '+') || (operator.peek() == '-') || (operator.peek() == '/') || (operator.peek() == '*'))) { oper(operator, operand); } operator.push(c); } else if (c == '/' || c == '*') { while (!operator.isEmpty() && ((operator.peek() == '/') || (operator.peek() == '*'))) { oper(operator, operand); } operator.push(c); } else if (c == '(') { operator.push(c); } else if (c == ')') { while (operator.peek() != '(') { oper(operator, operand); } operator.pop(); } else { operand.push(Integer.parseInt(text)); } } while (!operator.isEmpty()) { oper(operator, operand); ; } return operand.pop(); } public void oper(Stack<Character> operator, Stack<Integer> operand) { Integer num1 = operand.pop(); Integer num2 = operand.pop(); Character oper = operator.pop(); Integer ret = 0; if (oper == '-') ret = num2 - num1; if (oper == '+') ret = num2 + num1; if (oper == '*') ret = num2 * num1; if (oper == '/') { if (num1 == 0) { System.out.println("'0' can not be divided!"); } else { ret = num2 / num1; } } operand.push(ret); } public static void main(String[] args) { String[] exps = { "1+2", "3 * (4 + 5)", "(4 + 5) / 3 + (1 + 2*1)" }; System.out.println("---***---"); for (String exp : exps) { int ans = new CaculatorSimulate().caculate(exp); System.out.println(exp + " ==> " + ans); } } }
后记:
加强版的计算器可增加如下内容:
1.平方,根号等复杂运算
2.正负数
3.小数
后续有余力之时自当尽快补上!