使用栈来实现,可以处理运算优先级。

使用自然四则运算表达式即可,如: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 等,有什么问题可以随时留言,小编会及时回复大家的。感谢朋友们对网站的支持。
# java
# 四则混合运算
# 混合运算
# java实现随机输出300题四则运算
# java中实现四则运算代码
# java实现任意四则运算表达式求值算法
# 波兰
# 有什么
# 感兴趣
# 朋友们
# 浅谈
# 来实现
# 转换为
# 可以随时
# 小编
# 等形式
# 运算符
# START_END_MARK
# tokens
# push
# TERMINATE_TOKENS
# TOKENIZER
# Object
# token
# size
# instanceof
相关文章:
广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?
企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?
如何用狗爹虚拟主机快速搭建网站?
北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?
无锡营销型网站制作公司,无锡网选车牌流程?
c++怎么用jemalloc c++替换默认内存分配器【性能】
南京网站制作费用,南京远驱官方网站?
php json中文编码为null的解决办法
制作农业网站的软件,比较好的农业网站推荐一下?
如何用IIS7快速搭建并优化网站站点?
网站插件制作软件免费下载,网页视频怎么下到本地插件?
Dapper的Execute方法的返回值是什么意思 Dapper Execute返回值详解
如何基于云服务器快速搭建网站及云盘系统?
青浦网站制作公司有哪些,苹果官网发货地是哪里?
宝华建站服务条款解析:五站合一功能与SEO优化设置指南
建站之星IIS配置教程:代码生成技巧与站点搭建指南
潮流网站制作头像软件下载,适合母子的网名有哪些?
北京制作网站的公司,北京铁路集团官方网站?
兔展官网 在线制作,怎样制作微信请帖?
香港服务器租用费用高吗?如何避免常见误区?
如何用虚拟主机快速搭建网站?详细步骤解析
如何正确下载安装西数主机建站助手?
如何选择高效稳定的ISP建站解决方案?
如何用PHP快速搭建高效网站?分步指南
郑州企业网站制作公司,郑州招聘网站有哪些?
公司网站建设制作费用,想建设一个属于自己的企业网站,该如何去做?
视频网站制作教程,怎么样制作优酷网的小视频?
如何自定义建站之星模板颜色并下载新样式?
番禺网站制作公司哪家值得合作,番禺图书馆新馆开放了吗?
如何通过虚拟机搭建网站?详细步骤解析
javascript中对象的定义、使用以及对象和原型链操作小结
青岛网站建设如何选择本地服务器?
公司网站制作费用多少,为公司建立一个网站需要哪些费用?
高防服务器租用首荐平台,企业级优惠套餐快速部署
如何在宝塔面板中修改默认建站目录?
陕西网站制作公司有哪些,陕西凌云电器有限公司官网?
如何在云服务器上快速搭建个人网站?
已有域名建站全流程解析:网站搭建步骤与建站工具选择
网站建设设计制作营销公司南阳,如何策划设计和建设网站?
宝塔面板如何快速创建新站点?
济南网站建设制作公司,室内设计网站一般都有哪些功能?
如何高效配置香港服务器实现快速建站?
太原网站制作公司有哪些,网约车营运证查询官网?
如何通过wdcp面板快速创建网站?
如何在Windows服务器上快速搭建网站?
建站之星如何通过成品分离优化网站效率?
专业制作网站的公司哪家好,建立一个公司网站的费用.有哪些部分,分别要多少钱?
如何用好域名打造高点击率的自主建站?
如何用西部建站助手快速创建专业网站?
如何在IIS中配置站点IP、端口及主机头?
*请认真填写需求信息,我们会在24小时内与您取得联系。