Java —— 表达式计算器
2016-04-09 19:24
393 查看
Java —— 表达式计算器
在JavaScript中,我们知道有eval()这个函数,专门用来运行表达式字符串,用起来非常方便。但是在C++、Java中,就没有这么方便的工具给我们使用了。对一个表达式求值的步骤有两步:
① 中缀表达式求前缀表达式
② 前缀表达式运算求值
这两个步骤分别利用两个栈,操作符栈与操作数栈;
具体的讲解请参考《MFC 实现 加减乘除,括号,乘方的 计算器》
程序源代码:
import java.util.HashSet; import java.util.Scanner; import java.util.Set; import java.util.Stack; public class Work5 { // 操作数栈 private static Stack<Double> Operands; // 操作符栈 private static Stack<Character> Operators; // 操作符集合 private static final Set<Character> C_OperatorSet = new HashSet<Character>() { /** * */ private static final long serialVersionUID = 1L; { add('+'); add('-'); add('*'); add('/'); add('^'); add('('); add(')'); } }; private static int getOperatorPriority(char ch) { if (ch == '+' || ch == '-') return 0; else if (ch == '*' || ch == '/') return 1; else if (ch == '^') return 3; else return -1; } private static String infixToSuffix(String expression) { Operators = new Stack<>(); Operators.clear(); StringBuilder sBuilder = new StringBuilder(); for (int i = 0; i < expression.length(); i++) { char ch = expression.charAt(i); if (ch == ' ') continue; if (C_OperatorSet.contains(ch)) { if (Operators.empty()) { if (ch == ')') { System.out.println("括号不匹配"); return sBuilder.toString(); } Operators.push(ch); } else if (ch == '(') { Operators.push(ch); } else if (ch == ')') { char top; while ((top = Operators.peek()) != '(') { if (Operators.empty()) { System.out.println("括号不匹配"); return sBuilder.toString(); } sBuilder.append(top); Operators.pop(); } Operators.pop(); } else { char top = Operators.peek(); if (getOperatorPriority(ch) <= getOperatorPriority(top)) { while (!Operators.empty() && getOperatorPriority(ch) <= getOperatorPriority(top = Operators.peek())) { sBuilder.append(top); Operators.pop(); } } Operators.push(ch); } } else { sBuilder.append("[" + ch); while (i + 1 < expression.length() && (((ch = expression.charAt(i + 1)) == '.') || (ch >= '0' && ch <= '9'))) { sBuilder.append(ch); ++i; } sBuilder.append(']'); } } while (!Operators.empty()) { sBuilder.append(Operators.peek()); Operators.pop(); } return sBuilder.toString(); } public static double evalExp(String expression) { Operands = new Stack<>(); Operands.clear(); double ret = 0; String suffix = infixToSuffix(expression); System.out.println("suffix: " + suffix); for (int i = 0; i < suffix.length(); i++) { if (suffix.charAt(i) == '[') { i++; int beginIndex = i, endIndex = i; while (']' != suffix.charAt(i)) { i++; endIndex++; } Operands.push(Double.valueOf(suffix.substring(beginIndex, endIndex))); } else { double left, right, res = 0; right = Operands.peek(); Operands.pop(); left = Operands.peek(); Operands.pop(); switch (suffix.charAt(i)) { case '+': res = left + right; break; case '-': res = left - right; break; case '*': res = left * right; break; case '/': res = left / right; break; case '^': res = Math.pow(left, right); break; } Operands.push(res); } } ret = Operands.peek(); Operands.pop(); return ret; } public static void main(String[] args) { // TODO Auto-generated method stub Scanner input = new Scanner(System.in); System.out.println("请输入一个含+-*/^()的表达式,请确认输入合法"); String expression = input.nextLine(); System.out.println(expression + " =" + evalExp(expression)); input.close(); } }
相关文章推荐
- 未重新服务器而导致的错误java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is
- 文件传输基础——Java IO流
- 关于eclipse连接不到genymotion的问题,eclipsegenymotion
- Eclipse下开发Spark程序碰到的一个错误
- Java NIO(6)----NIO与IO
- Java NIO(5)----Pipe
- Java 笔记(1)
- Java NIO(4)----几种Channel
- Eclipse安装PyDev插件
- JVM-并发-Java 内存模型
- java毕向东听课笔记11(异常体系)
- RSA加解密算法java实现(已添加分段加密算法处理)
- Java实验2 类的继承性
- java.lang.ExceptionInInitializerError的原因
- Spring的Bean组件
- Java NIO(3)----Selector
- JDK内置工具
- Java NIO(2)----数据传输
- Java有序表查找:折半查找、二分查找、差值查找和斐波那契查找
- JAVA中堆和栈的区别