Java实现四则混合运算代码示例
时间:2019-04-07
本文章向大家介绍Java实现四则混合运算代码示例,主要包括Java实现四则混合运算代码示例使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
使用栈来实现,可以处理运算优先级。
使用自然四则运算表达式即可,如:4+(3*(3-1)+2)/2。无需把表达式先转换为逆波兰等形式。
package com.joshua.cal; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Stack; public class Calculator { private final Stack<Double> numStack = new Stack<Double>(); private final Stack<Character> opStack = new Stack<Character>(); private char currentOperator; private char opStackTop; private int i; private String expression; @SuppressWarnings("rawtypes") public void exec(String expression) { try { clean(); if (expression == null || expression.isEmpty()) { throw new IllegalArgumentException("Blank Expression!"); } this.expression = expression; opStack.push(TERMINATE_TOKENS.START_END_MARK); List tokens = TOKENIZER.exec(expression + TERMINATE_TOKENS.START_END_MARK); for (; i < tokens.size(); i++) { final Object token = tokens.get(i); if (token instanceof Double) { processOperand((double) token); } else { processOperator((char) token); } } } catch (Throwable e) { System.err.println(String.format( "Incorret Expression: %s\nError: %s", expression, e.getMessage())); } } private void processOperand(final double operand) { numStack.push(operand); } private void processOperator(final char currentOperator) { this.currentOperator = currentOperator; this.opStackTop = opStack.peek(); char calMode = CALCULATE_MODE.getRule(currentOperator, opStackTop); switch (calMode) { case '>': processStackHigerPriorityOperator(); break; case '<': processStackLowerPriorityOperator(); break; case '=': processStackEqualPriorityOperator(); break; default: break; } } private void processStackLowerPriorityOperator() { opStack.push(currentOperator); } private void processStackHigerPriorityOperator() { numStack.push(CALCULATE.exec(opStack.pop(), numStack.pop(), numStack.pop())); --i; // pointer back to the previous operator. } private void processStackEqualPriorityOperator() { if (TERMINATE_TOKENS.START_END_MARK == currentOperator) { System.out.println(expression + " = " + numStack.peek()); } else if (')' == currentOperator) { opStack.pop(); } } public void clean() { numStack.clear(); opStack.clear(); i = 0; } public static void main(String[] args) { Calculator cal = new Calculator(); cal.exec("4+(3*(3-1)+2)/2"); // = 8 cal.exec("4 + (-3 * ( 3 - 1 ) + 2)"); // = 0 cal.exec("4 +-/ (-3 * ( 3 - 1 ) + 2)"); // incorrect expression! cal.exec("4.5+(3.2+3)/2"); // = 7.6 cal.exec("4.5+(3.2:3)/2"); // incorrect expression! cal.exec("-4.5+(3.2-3)/2"); // = -4.4 } } enum CALCULATE { INSTANCE; public static double exec(final char operator, final double right, final double left) { switch (operator) { case '+': return left + right; case '-': return left - right; case '*': return left * right; case '/': return left / right; default: throw new IllegalArgumentException("Unsupported operator: " + operator); } } } enum TERMINATE_TOKENS { INSTANCE; public static final char START_END_MARK = '#'; private static final Map<Character, Integer> TOKENs = new HashMap<Character, Integer>(); static { // token, token id TOKENs.put('+', 0); TOKENs.put('-', 1); TOKENs.put('*', 2); TOKENs.put('/', 3); TOKENs.put('(', 4); TOKENs.put(')', 5); TOKENs.put(START_END_MARK, 6); } private static Set<Character> NEGATIVE_NUM_SENSITIVE = new HashSet<Character>(); public static synchronized Set<Character> getNegativeNumSensitiveToken() { if (NEGATIVE_NUM_SENSITIVE.size() == 0) { NEGATIVE_NUM_SENSITIVE.addAll(TOKENs.keySet()); NEGATIVE_NUM_SENSITIVE.remove(')'); } return NEGATIVE_NUM_SENSITIVE; } public static boolean isTerminateToken(final char token) { Set<Character> keys = TOKENs.keySet(); return keys.contains(token); } public static int getTokenId(final char token) { return TOKENs.get(token) == null ? -1 : TOKENs.get(token); } public static int getTokenSize() { return TOKENs.size(); } } enum CALCULATE_MODE { INSTANCE; private static char[][] RULES = { // + - * / ( ) # { '>', '>', '<', '<', '<', '>', '>' }, // + { '>', '>', '<', '<', '<', '>', '>' }, // - { '>', '>', '>', '>', '<', '>', '>' }, // * { '>', '>', '>', '>', '<', '>', '>' }, // / { '<', '<', '<', '<', '<', '=', 'o' }, // ( { '>', '>', '>', '>', 'o', '>', '>' }, // ) { '<', '<', '<', '<', '<', 'o', '=' }, // # }; static { if (RULES.length != TERMINATE_TOKENS.getTokenSize() || RULES.length < 1 || RULES[0].length != TERMINATE_TOKENS.getTokenSize()) { throw new IllegalArgumentException("Rules matrix is incorrect!"); } } public static char getRule(final char currentOperator, final char opStackTop) { try { return RULES[TERMINATE_TOKENS.getTokenId(opStackTop)][TERMINATE_TOKENS .getTokenId(currentOperator)]; } catch (Throwable e) { throw new RuntimeException("No rules were defined for some token!"); } } } enum TOKENIZER { INSTANCE; private static final StringBuilder BUFFER = new StringBuilder(); private static String clearExpression(String expression) { return expression.replaceAll(" ", ""); } private static Character PREVIOUS_CHAR; private static void clean() { BUFFER.delete(0, BUFFER.length()); PREVIOUS_CHAR = null; } private static boolean processNegativeNumbers(final String exp, final int index) { char c = exp.charAt(index); if (('+' == c || '-' == c) && (PREVIOUS_CHAR == null || TERMINATE_TOKENS .getNegativeNumSensitiveToken().contains(PREVIOUS_CHAR)) && !TERMINATE_TOKENS.isTerminateToken(exp.charAt(index + 1))) { BUFFER.append(c); return true; } return false; } @SuppressWarnings({ "unchecked", "rawtypes" }) public static List<?> exec(final String expression) { clean(); String exp = clearExpression(expression); List result = new LinkedList(); for (int i = 0; i < exp.length(); i++) { char c = exp.charAt(i); if (TERMINATE_TOKENS.isTerminateToken(c)) { if (processNegativeNumbers(exp, i)) continue; if (BUFFER.length() > 0) { result.add(Double.valueOf(BUFFER.toString())); BUFFER.delete(0, BUFFER.length()); } result.add(c); } else { BUFFER.append(c); } PREVIOUS_CHAR = c; } return Collections.unmodifiableList(result); } }
输出
4+(3*(3-1)+2)/2 = 8.0 4 + (-3 * ( 3 - 1 ) + 2) = 0.0 4.5+(3.2+3)/2 = 7.6 -4.5+(3.2-3)/2 = -4.4 Incorret Expression: 4 +-/ (-3 * ( 3 - 1 ) + 2) Error: null Incorret Expression: 4.5+(3.2:3)/2 Error: For input string: "3.2:3"
总结
以上就是本文关于Java实现四则混合运算代码示例的全部内容,希望对大家有所帮助。感兴趣的朋友可以参阅:大话Java混合运算规则 浅谈Java变量赋值运算符及相关实例 Java大数字运算之BigInteger 等,有什么问题可以随时留言,小编会及时回复大家的。感谢朋友们对脚本之家网站的支持。
- 零基础学编程007:FOR循环
- 零基础学编程006:赋值语句
- 零基础学编程005:打印一行复利数据
- 使用Keras集成卷积神经网络的入门级教程
- 零基础学编程003:在游戏中学JAVA和C#
- 在机器学习中处理缺失数据的方法
- 零基础学编程002:Hello World
- php随机数怎么获取?一个简单的函数就能生成
- 零基础学编程009:只显示2位小数
- .Net实现Windows服务安装完成后自动启动的两种方法
- 【教程】OpenCV—Node.js教程系列:Node.js+OpenCV面部脸识别
- 学会10多种语言是种什么样的体验?
- Spring Data 最佳实践
- Prodigy,从根本上有效的自主学习驱动的注释工具
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 给你总结几个ES下最容易踩的坑
- ES系列之利用filter让你的查询效率飞起来
- ES主分片和副本数据大小不一样的情况
- 关于kibana的可视化可能都在这篇文章里了
- ES分页看这篇就够了
- ES系列之原来查看文档数量有这么多姿势
- ES系列之嵌套文档和父子文档
- ES系列之一文带你避开日期类型存在的坑
- ES系列之原来ES的聚合统计不准确啊
- fastjson远程代码执行漏洞问题分析
- 数据库连接池的原理没你想得这么复杂
- 你真的会用volatile吗
- 你真的了解LinkedBlockingQueue的put,add和offer的区别吗
- 关于Java使用groupingBy分组数据乱序问题
- 详解 java CompletableFuture