下面题目是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算法学习----逆波兰表达式求值(后缀表达式)的更多相关文章

  1. NYOJ 35 表达式求值(逆波兰式求值)

    http://acm.nyist.net/JudgeOnline/problemset.php?typeid=4 NYOJ 35 表达式求值(逆波兰式求值) 逆波兰式式也称后缀表达式. 一般的表达式求 ...

  2. 中缀表达式变后缀表达式、后缀表达式(逆波兰)求值(python版本)

    定义: 中缀表达式: 在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表达式 后缀表达式: 又叫逆波兰表达式 ,不包含括号,运算符放在两个运算对象的后面,所有的计算 ...

  3. TOJ1302: 简单计算器 && TOJ 4873: 表达式求值&&TOJ3231: 表达式求值

    这些都是应用Python的eval函数的一些题目! TOJ1302传送门:http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=show ...

  4. C++基础算法学习——逆波兰表达式问题

    例题:逆波兰表达式逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3.逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 ...

  5. ACM-ICPC 2018 沈阳赛区网络预赛 B Call of Accepted(表达式求值)

    题目链接:https://nanti.jisuanke.com/t/31443 相关前置链接 https://www.cnblogs.com/dolphin0520/p/3708602.html ht ...

  6. 【足迹C++primer】表达式求值

    表达式求值 /** * 功能:表达式求值(0到9) * 时间:2014年6月15日08:02:31 * 作者:cutter_point */ #include<stdlib.h> #inc ...

  7. java实现算术表达式求值

    需要根据配置的表达式(例如:5+12*(3+5)/7.0)计算出相应的结果,因此使用java中的栈利用后缀表达式的方式实现该工具类. 后缀表达式就是将操作符放在操作数的后面展示的方式,例如:3+2 后 ...

  8. LeetCode 150. 逆波兰表达式求值(Evaluate Reverse Polish Notation) 24

    150. 逆波兰表达式求值 150. Evaluate Reverse Polish Notation 题目描述 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, /.每个运算对象 ...

  9. LeetCode:逆波兰表达式求值【150】

    LeetCode:逆波兰表达式求值[150] 题目描述 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除 ...

随机推荐

  1. base64编码上传图片java后台接收实例

    原文地址:http://blog.csdn.net/tonyfreak/article/details/72522855 思路 前台传以data:image/jpeg;base64,开头的base64 ...

  2. MySQL 四种事务隔离级别详解及对比--转

    http://www.jb51.net/article/100183.htm 接的隔离级别.它的语法如下: ? 1 SET [SESSION | GLOBAL] TRANSACTION ISOLATI ...

  3. Spring框架学习-Spring和IOC概述

    一:什么是Spring框架? spring是一个分层的javase/EEfull-stack(一站式)轻量级的java开源框架.是为了解决企业开发的复杂性而创建的.框架的主要优势是分层架构,Sprin ...

  4. Java编程思想读书笔记_第7章

    final关键字类似const: import java.util.*; public class FinalData { static Random rand = new Random(47); f ...

  5. [ Nowcoder Contest 167 #D ] 重蹈覆辙

    \(\\\) \(Description\) 用\(1\times 2\)的矩形和面积为\(3\)的\(L\)形去覆盖一个\(2\times N\) 的矩形,求方案数对\(10^4+7\)取模后的结果 ...

  6. sublime 设置浏览器

    方法一: 1.安装sidebarenhancements插件 ctrl+shift+p —> Install Package —> 找到SideBarEnhancements 2.配置预览 ...

  7. 解决安装androidstudio无法查看源代码的问题

    如果androidstudio的sdk是自己导入的,则可能会有查看不了源代码的原因.原因是默认目录中没有这个api的源代码. 1.先在C:\Users\xxx\.AndroidStudio2.3\co ...

  8. APP上线被APPStore拒绝的各种原因

    1.程序有重大bug,程序不能启动,或者中途退出.2.绕过苹果的付费渠道,我们之前游戏里的用兑换码兑换金币.3.游戏里有实物奖励的话,一定要说清楚,奖励由本公司负责,和苹果没有关系.4.用到苹果的标志 ...

  9. dubbo-monitor安装及配置过程

    安装 1. 使用git下载(git clone https://github.com/alibaba/dubbo.git)或者从http://dubbo.io/下载源码 2. cd到dubbo的根目录 ...

  10. MySql (二)入门语句和基本操作

    mysql的入门语句:查看服务器下的库 show databases; 创建库(数据库被创建后它的名字是不可以更改的) create database 数据库名; 2.1.插看当前所在的库 selec ...