leetcode算法学习----逆波兰表达式求值(后缀表达式)
下面题目是LeetCode算法:逆波兰表达式求值(java实现)
逆波兰表达式即后缀表达式。
题目:
有效的运算符包括 +, -, *, / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式、同时支持括号。(假设所有的数字均为整数,不考虑精度问题)
计算工具:
/**
* 计算工具
* @author monkjavaer
* @date 2018/9/13 14:35
*/
public class CalculatorUtil {
/**
* 加
*/
private static final String ADD = "+";
/**
* 减
*/
private static final String SUBTRACT = "-";
/**
* 乘
*/
private static final String MULTIPLICATION = "*";
/**
* 除
*/
private static final String DIVISION = "/";
/**
* 左括号
*/
private static final String LEFT_PARENTHESIS = "(";
/**
* 右括号
*/
private static final String RIGHT_PARENTHESIS = ")"; /**
*
* 提供给外部的计算方法
*
* @param expression 后缀表达式
* @return 计算结果
*/
public static int calculation(Expression expression) throws Exception {
List<String> list = getPostfix(expression);
Stack<Integer> calculationStack = new Stack<>();
Integer operandRight;
Integer operandLeft;
for (String item : list) {
if (ADD.equals(item)) {
operandRight = calculationStack.pop();
operandLeft = calculationStack.pop();
calculationStack.push(operandLeft + operandRight);
} else if (SUBTRACT.equals(item)) {
operandRight = calculationStack.pop();
operandLeft = calculationStack.pop();
calculationStack.push(operandLeft - operandRight);
} else if (MULTIPLICATION.equals(item)) {
operandRight = calculationStack.pop();
operandLeft = calculationStack.pop();
calculationStack.push(operandLeft * operandRight);
} else if (DIVISION.equals(item)) {
operandRight = calculationStack.pop();
operandLeft = calculationStack.pop();
calculationStack.push(operandLeft / operandRight);
} else {
calculationStack.push(Integer.parseInt(item));
}
} return calculationStack.pop();
} /**
* 判断字符为运算符(+,-,*,/)
*
* @param c 输入字符
* @return
*/
private static boolean isOperator(char c) { return ADD.equals(String.valueOf(c)) || SUBTRACT.equals(String.valueOf(c)) ||
MULTIPLICATION.equals(String.valueOf(c)) || DIVISION.equals(String.valueOf(c));
} /**
* 返回的是运算符的优先级
*
* @param operator
* @return
*/
private static int priority(Operator operator) {
char operatorName = operator.getOperatorName();
if (ADD.equals(String.valueOf(operatorName)) || SUBTRACT.equals(String.valueOf(operatorName))) {
return 1;
} else if (MULTIPLICATION.equals(String.valueOf(operatorName)) || DIVISION.equals(String.valueOf(operatorName))) {
return 2;
} else {
return 0;
}
} /**
* 通过表达式获得后缀表达式
*
* @param expression
* @return
*/
private static List<String> getPostfix(Expression expression) throws Exception {
/**
* 操作符栈
*/
Stack<Operator> operatorStack = new Stack<>(); /**
* 存放后缀表达式
*/
List<String> operandList = new ArrayList<>(); String expressionStr = expression.getExpressionStr();
for (int i = 0; i < expressionStr.length(); i++) {
char oneChar = expressionStr.charAt(i); Operator operator = new Operator();
operator.setOperatorName(oneChar); //遇到操作数:直接输出(添加到后缀表达式中)
if (Character.isDigit(oneChar)) {
int num = oneChar - '0';
while (i + 1 < expressionStr.length() && Character.isDigit(expressionStr.charAt(i + 1))) {
num = num * 10 + expressionStr.charAt(i + 1) - '0';
i++;
}
operandList.add(String.valueOf(num));
} else if (LEFT_PARENTHESIS.equals(String.valueOf(oneChar))) {
//遇到左括号:将其入栈
operatorStack.push(operator);
} else if (RIGHT_PARENTHESIS.equals(String.valueOf(oneChar))) {
//遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
while (!LEFT_PARENTHESIS.equals(String.valueOf(operatorStack.peek().getOperatorName()))) {
operandList.add(String.valueOf(operatorStack.pop().getOperatorName()));
}
//然后弹出左括号
operatorStack.pop();
} else if (isOperator(oneChar)) {
//遇到运算符
//栈为空时,直接入栈
if (operatorStack.isEmpty()) {
operatorStack.push(operator);
} else {
// 如果读入的操作符为非")"且优先级比栈顶元素的优先级高或一样
if (priority(operatorStack.peek()) < priority(operator)) {
operatorStack.push(operator);
} else if (priority(operatorStack.peek()) >= priority(operator)) {
operandList.add(String.valueOf(operatorStack.pop().getOperatorName()));
operatorStack.push(operator);
}
}
}
} //最终将栈中的元素依次出栈。
while (!operatorStack.isEmpty()) {
operandList.add(String.valueOf(operatorStack.pop().getOperatorName()));
}
System.out.println(operandList);
return operandList;
} }
表达式:
/**
* 表达式
*
* @author monkjavaer
* @date 2018/9/12 19:42
*/
public class Expression { /**
* 表达式名字
*/
private String name; /**
* 表达式
*/
private String expressionStr; /**
* 表达式值
*/
private int value; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getExpressionStr() {
return expressionStr;
} public void setExpressionStr(String expressionStr) {
this.expressionStr = expressionStr;
} public int getValue() {
return value;
} public void setValue(int value) {
this.value = value;
} }
操作数:
/**
* 操作数
* @author monkjavaer
* @date 2018/9/12 19:43
*/
public class Operand {
/**
* 操作数值
*/
private Integer operandValue; public Integer getOperandValue() {
return operandValue;
} public void setOperandValue(Integer operandValue) {
this.operandValue = operandValue;
}
}
运算符:
/**
* 运算符
*
* @author monkjavaer
* @date 2018/9/12 19:43
*/
public class Operator {
/**
* 运算符符号
*/
private char operatorName; public char getOperatorName() {
return operatorName;
} public void setOperatorName(char operatorName) {
this.operatorName = operatorName;
} }
测试:
/**
* @author monkjavaer
* @date 2018/9/13 11:49
*/
public class Test { public static void main(String[] args) {
Expression expression = new Expression();
expression.setExpressionStr("4 +(13 - 5)");
try {
System.out.println(CalculatorUtil.calculation(expression));
} catch (Exception e) {
e.printStackTrace();
}
} }
leetcode算法学习----逆波兰表达式求值(后缀表达式)的更多相关文章
- NYOJ 35 表达式求值(逆波兰式求值)
http://acm.nyist.net/JudgeOnline/problemset.php?typeid=4 NYOJ 35 表达式求值(逆波兰式求值) 逆波兰式式也称后缀表达式. 一般的表达式求 ...
- 中缀表达式变后缀表达式、后缀表达式(逆波兰)求值(python版本)
定义: 中缀表达式: 在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表达式 后缀表达式: 又叫逆波兰表达式 ,不包含括号,运算符放在两个运算对象的后面,所有的计算 ...
- TOJ1302: 简单计算器 && TOJ 4873: 表达式求值&&TOJ3231: 表达式求值
这些都是应用Python的eval函数的一些题目! TOJ1302传送门:http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=show ...
- C++基础算法学习——逆波兰表达式问题
例题:逆波兰表达式逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3.逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 ...
- ACM-ICPC 2018 沈阳赛区网络预赛 B Call of Accepted(表达式求值)
题目链接:https://nanti.jisuanke.com/t/31443 相关前置链接 https://www.cnblogs.com/dolphin0520/p/3708602.html ht ...
- 【足迹C++primer】表达式求值
表达式求值 /** * 功能:表达式求值(0到9) * 时间:2014年6月15日08:02:31 * 作者:cutter_point */ #include<stdlib.h> #inc ...
- java实现算术表达式求值
需要根据配置的表达式(例如:5+12*(3+5)/7.0)计算出相应的结果,因此使用java中的栈利用后缀表达式的方式实现该工具类. 后缀表达式就是将操作符放在操作数的后面展示的方式,例如:3+2 后 ...
- LeetCode 150. 逆波兰表达式求值(Evaluate Reverse Polish Notation) 24
150. 逆波兰表达式求值 150. Evaluate Reverse Polish Notation 题目描述 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, /.每个运算对象 ...
- LeetCode:逆波兰表达式求值【150】
LeetCode:逆波兰表达式求值[150] 题目描述 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除 ...
随机推荐
- mysql的大数据量的查询
mysql的大数据量查询分页应该用where 条件进行分页,limit 100000,100,mysql先查询100100数据量,查询完以后,将 这些100000数据量屏蔽去掉,用100的量,但是如果 ...
- GIt学习之路 第二天 创建版本库
本文参考廖雪峰老师的博客进行总结,完整学习请转廖雪峰博客 创建版本库 阅读: 1859216 什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文 ...
- O - Combinations (组合数学)
Description Computing the exact number of ways that N things can be taken M at a time can be a great ...
- Git在工作中对项目的操作流程
Git 的准备工作 第一步:Git初始化 第一次在电脑上使用时,应该初始化操作,以后再使用Git操作,无需初始化,直接进行Git其他操作 git config --global user.name & ...
- Python学习日记之快捷键
Alt+Enter 自动添加包Ctrl+t SVN更新Ctrl+k SVN提交Ctrl + / 注释(取消注释)选择的行Ctrl+Shift+F 高级查找Ctrl+Enter 补全Shift + En ...
- Smarty的应用
smarty模板的核心是一个类,下载好的模板中有这么几个重要的文件夹 (1)libs核心文件夹(2)int.inc.php这是入口文件(3)plugins:自己写的插件文件夹(4)templates_ ...
- tensorboard在windows系统浏览器显示空白的解决
一个简单的using_tensorboard.py程序,如下: #using_tensorboard.py import tensorflow as tf a = tf.constant(10,nam ...
- 【译】x86程序员手册31- 第9章 异常和中断
Chapter 9 Exceptions and Interrupts 第9章 异常和中断 Interrupts and exceptions are special kinds of control ...
- docloud后台管理项目(开篇)
最近朋友做app需要web做后台管理,所以花了一周时间做了这个项目. 废话不多说,开发环境是nginx+php5.3,使用thinkphp框架.是一个医疗器械数据统计的后台,业务功能很简单就是查看用户 ...
- arx代码片段
ObjectARX代码片段二 转载自网络 一 在ARX中禁用AutoCAD的某个命令 以LINE命令为例,在程序中加入下面的一句即可禁用LINE命令: acedCommand(RTSTR, &q ...