直接上代码:

public class PolandCalculator {
//栈的应用:波兰计算器: 即: 输入一个字符串,来计算结果, 比如 1+((2+3)×4)-5 结果为16
public static void main(String[] args) throws Exception {
/**
* 思路:
* 1: 将 1+((2+3)×4)-5 (这叫中缀表达式,运算符再数字中间), 转换为后缀表达式 (1 2 3 + 4 × + 5 –)
* 2: 使用栈, 将后缀表达式 , 计算得出结果
*
* 因为 后缀表达式, 来计算会变得简单易懂, 不需要那么多的判断, 只需要 数入栈,然后判断运算符, 从栈中pop出二个数,计算,并把结果入栈, 循环往复,得到最终结果
*/ String str = "1+((2+3)*4)-5";
// 1, 先将 str 字符串变为对应的 中缀表达式 midExpressionList(便于显示)
List<String> midExpressionList = toMidExpressionList(str);
System.out.println("前缀表达式为: "+midExpressionList);
// 2, 将 midExpressionList 转换为 后缀表达式对应的 suffixExpressionList
List<String> suffixExpressionList = toSuffixExpressionList(midExpressionList);
System.out.println("后缀表达式为: "+suffixExpressionList);
// 3, 计算结果
calculator(suffixExpressionList);
} private static List<String> toMidExpressionList(String s) {
//定义一个List,存放中缀表达式 对应的内容
List<String> ls = new ArrayList<String>();
int i = 0; //这时是一个指针,用于遍历 中缀表达式字符串
String str; // 对多位数的拼接
char c; // 每遍历到一个字符,就放入到c
do {
//如果c是一个非数字,我需要加入到ls
if((c=s.charAt(i)) < 48 || (c=s.charAt(i)) > 57) {
ls.add("" + c);
i++; //i需要后移
} else { //如果是一个数,需要考虑多位数
str = ""; //先将str 置成"" '0'[48]->'9'[57]
while(i < s.length() && (c=s.charAt(i)) >= 48 && (c=s.charAt(i)) <= 57) {
str += c;//拼接
i++;
}
ls.add(str);
}
}while(i < s.length());
return ls;//返回
} private static List<String> toSuffixExpressionList(List<String> midExpressionList) {
//1, 定义一个栈 用来存运算符
Stack<String> cal = new Stack<String>();
//2, 定义一个list 来做存中间结果和返回, 也可以定义一个栈, 但是用栈的话, 这个转换过程并没有pop操作, 而且还要逆序显示,比较麻烦, 所以用list
List<String> resList = new ArrayList<String>();
for (String str : midExpressionList) {
if(str.matches("\\d+")){
//是一个或多个数字, 就存入resList
resList.add(str);
}else if (str.equals("(")){
//如果是 左括号 , 就加入cal 栈
cal.push(str);
}else if(str.equals(")")){
//如果是右括号, 此时需要将cal 栈的运算符号,依次pop,并加入到resList中, 直到遇到"左括号"停止, 最后将"左括号"删除
while(! cal.peek().equals("(")){
resList.add(cal.pop());
}
cal.pop();//跳出循环时,已经将"("之前的运算符都存入resList中, 此一步是将"("删除
}else {
//是运算符 +,-,*,/ , 如果是运算符, 如果cal栈为空,直接加入栈, 如果该运算符 优先级小于等于 cal栈顶运算符, 将cal栈中运算符 依次pop,加入到resList中, 知道运算符优先级大于为止
while(cal.size() != 0 && operator(str) <= operator(cal.peek())){
resList.add(cal.pop());
}
cal.push(str);
}
}
//最后将 cal栈中的运算符依次弹出加入到resList中
while(cal.size() != 0){
resList.add(cal.pop());
}
return resList;
} private static int operator(String str) {
if(str.equals("+") || str.equals("-")){
return 1;
}
if(str.equals("*") || str.equals("/")){
return 2;
}
return 0;
} private static void calculator(List<String> suffixExpressionList) throws Exception {
Stack<String> stack = new Stack<>(); for (String str : suffixExpressionList) {
if(str.matches("\\d+")){
//是数字, 入栈
stack.push(str);
}else{
//是运算符, 从栈中pop二个数, 计算,将计算结果存入stack中, 最终stack中的数, 就是计算结果
int num2 = Integer.parseInt(stack.pop());
int num1 = Integer.parseInt(stack.pop());
int res = 0; if(str.equals("+")){
res = num1 + num2;
} else if(str.equals("-")){
res = num1 - num2;
} else if(str.equals("*")){
res = num1 * num2;
} else if(str.equals("/")){
res = num1 / num2;
} else{
throw new Exception("没有这个运算符:"+str);
}
//计算结果 入栈
stack.push(String.valueOf(res));
}
}
System.out.println("最终的计算结果为:" + stack.pop());
} }

测试结果:

在测试一个:

6, java数据结构和算法: 栈的应用, 逆波兰计算器, 中缀表达式--> 后缀表达式的更多相关文章

  1. Java数据结构和算法(六):前缀、中缀、后缀表达式

    前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...

  2. Java数据结构和算法 - 栈和队列

    Q: 栈.队列与数组的区别? A: 本篇主要涉及三种数据存储类型:栈.队列和优先级队列,它与数组主要有如下三个区别: A: (一)程序员工具 数组和其他的结构(栈.队列.链表.树等等)都适用于数据库应 ...

  3. java 数据结构与算法---栈

    原理来自百度百科 一.栈的定义 栈是一种只能在一端进行插入和删除操作的特殊线性表:它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数 ...

  4. 5, java数据结构和算法: 栈 , 入栈, 出栈, 正序遍历,,逆序遍历

    直接上代码: class ArrayStack{ //用数组模拟栈 int maxSize; int[] stack; int top = -1;//表示栈顶 public ArrayStack(in ...

  5. 【Java数据结构学习笔记之二】Java数据结构与算法之栈(Stack)实现

      本篇是java数据结构与算法的第2篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型   栈是 ...

  6. java数据结构与算法之栈(Stack)设计与实现

    本篇是java数据结构与算法的第4篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型 栈是一种用于 ...

  7. Java数据结构和算法(一)--栈

    栈: 英文名stack,特点是只允许访问最后插入的那个元素,也就是LIFO(后进先出) jdk中的stack源码: public class Stack<E> extends Vector ...

  8. Java数据结构和算法(六)——前缀、中缀、后缀表达式

    前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...

  9. Java数据结构和算法 - 二叉树

    前言 数据结构可划分为线性结构.树型结构和图型结构三大类.前面几篇讨论了数组.栈和队列.链表都是线性结构.树型结构中每个结点只允许有一个直接前驱结点,但允许有一个以上直接后驱结点.树型结构有树和二叉树 ...

随机推荐

  1. GNU C++的符号改编机制介绍(函数的名称粉碎格式解析)

    转载:http://blog.csdn.net/roland_sun/article/details/43233565 众所周知,强大的C++相较于C增添了许多功能.这其中就包括类.命名空间和重载这些 ...

  2. hdu4973 线段树(题目不错,用了点,段,更新查找还有DFS)

    题意:       给你一个初始序列,初始序列长度n,分别为1 2 3 4 5 ....n,有两种操作 (1)D l r 把l_r之间的数据都复制一遍 1 2 3 4 5 6 D 2 4 = 1 2 ...

  3. Python中hashlib模块的使用

    hashlib是 python 下一款与加密相关的库包,提供摘要算法:md5.sha1.sha224.sha256.sha384.sha512.blake2b.blake2s.sha3_224.sha ...

  4. Intel汇编语言程序设计学习-第三章 汇编语言基础-下

    3.4  定义数据 3.4.1  内部数据类型 MASM定义了多种内部数据类型,每种数据类型都描述了该模型的变量和表达式的取值集合.数据类型的基本特征是以数据位的数目量的大小:8,16,32,,48, ...

  5. 逆向与分析-WebBrowserPassView消息分析

    逆向与分析-WebBrowserPassView消息分析 这个的源头是之前我写的一个博客: http://blog.csdn.net/u013761036/article/details/730427 ...

  6. 【opencv】Java实现的opencv3.x版本后Highhui报错

    随笔为博主原创,如需转载,请注明出处. opencv3.x以后Highgui不再使用,用Imgcodecs代替,引入import org.opencv.imgcodecs.Imgcodecs;即可. ...

  7. 将本地代码上传到云效git存放

    前提已开通云效账号,然后进行云效首页的研发---代码 创建git组 创建git库 生成https://code.aliyun.com/test-demo1/v1的git库 准备将本地的test-dem ...

  8. 基于python对B站收藏夹按照视频发布时间进行排序

    基于python对B站收藏夹按照视频发布时间进行排序 前言 在最一开始,我的B站收藏一直是存放在默认收藏夹中,但是随着视频收藏的越来越多,没有分类的视频放在一起,想在众多视频中找到想要的视频非常困难, ...

  9. Django(17)orm查询操作

    前言 查找是数据库操作中一个非常重要的技术.查询一般就是使用filter.exclude以及get三个方法来实现.我们可以在调用这些方法的时候传递不同的参数来实现查询需求.在ORM层面,这些查询条件都 ...

  10. linux下符号链接和硬链接的区别

    存在2众不同类型的链接,软链接和硬链接,修改其中一个,硬链接指向的是节点(inode),软链接指向的是路径(path) 软连接文件 软连接文件也叫符号连接,这个文件包含了另一个文件的路径名,类似于wi ...