leetcode算法学习----逆波兰表达式求值(后缀表达式)

时间:2022-11-07 17:24:09

下面题目是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. 中缀表达式变后缀表达式、后缀表达式(逆波兰)求值&lpar;python版本&rpar;

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

  3. TOJ1302&colon; 简单计算器 &amp&semi;&amp&semi; TOJ 4873&colon; 表达式求值&amp&semi;&amp&semi;TOJ3231&colon; 表达式求值

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

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

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

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

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

  6. 【足迹C&plus;&plus;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&period; 逆波兰表达式求值&lpar;Evaluate Reverse Polish Notation&rpar; 24

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

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

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

随机推荐

  1. YYModel 源码解读(一)之YYModel&period;h

    #if __has_include(<YYModel/YYModel.h>) FOUNDATION_EXPORT double YYModelVersionNumber; FOUNDATI ...

  2. 【原创】开源Math&period;NET基础数学类库使用&lpar;06&rpar;直接求解线性方程组

                   本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新  开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...

  3. wpa&lowbar;supplicant 移植及 linux 命令行模式配置无线上网

    本文涉及内容为linux 命令行模式配置无线上网 及 wpa_supplicant 移植到开发板的过程,仅供参考. 1.源码下载 wpa_supplicant 源码下载地址 :http://hosta ...

  4. 【linux】具体芯片MACHINE&lowbar;START处理

    欢迎转载,转载时需保留作者信息,谢谢. 邮箱:tangzhongp@163.com 博客园地址:http://www.cnblogs.com/embedded-tzp Csdn博客地址:http:// ...

  5. 初步学习nodejs,业余用node写个一个自动创建目录和文件的小脚本,希望对需要的人有所帮助

    初步学习nodejs,业余用node写个一个自动创建目录和文件的小脚本,希望对需要的人有所帮助,如果有bug或者更好的优化方案,也请批评与指正,谢谢,代码如下: var fs = require('f ...

  6. HTML5 Web缓存&amp&semi;运用程序缓存&amp&semi;cookie&comma;session

    在介绍HTML5 web缓存前,来认识一下cookie和session: session: 由于HTTP是无状态的,你是谁?你干了什么?抱歉服务器都是不知道的. 因此session(会话)出现了,它会 ...

  7. Kubernetes的负载均衡问题&lpar;Nginx Ingress&rpar;

    nginx 反向代理 https://www.cnblogs.com/ericnie/p/6965091.html Kubernetes 集群中使用 Traefik https://blog.csdn ...

  8. java&period;lang&period;NoSuchMethodError&colon; org&period;springframework&period;web&period;context&period;ConfigurableWebApplicationContext&period;getEnvironment&lpar;&rpar;Lorg&sol;springframework&sol;core&sol;env&sol;ConfigurableEnvironment&semi;问题

    在springsecurity学习中,在加入spring有关的jar包后,出现java.lang.NoSuchMethodError: org.springframework.web.context. ...

  9. JS学习笔记5&lowbar;DOM

    1.DOM节点的常用属性(所有节点都支持) nodeType:元素1,属性2,文本3 nodeName:元素标签名的大写形式 nodeValue:元素节点为null,文本节点为文本内容,属性节点为属性 ...

  10. C&num;连接sqlserver windows 和 sqlserver 身份验证的两种连接字符串

    //sql server 身份验证 连接字符串 private string ConnstrSqlServer = "server=服务器名称;uid=登录名称;pwd=登录密码;datab ...