6, java数据结构和算法: 栈的应用, 逆波兰计算器, 中缀表达式--> 后缀表达式
直接上代码:
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数据结构和算法: 栈的应用, 逆波兰计算器, 中缀表达式--> 后缀表达式的更多相关文章
- Java数据结构和算法(六):前缀、中缀、后缀表达式
前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...
- Java数据结构和算法 - 栈和队列
Q: 栈.队列与数组的区别? A: 本篇主要涉及三种数据存储类型:栈.队列和优先级队列,它与数组主要有如下三个区别: A: (一)程序员工具 数组和其他的结构(栈.队列.链表.树等等)都适用于数据库应 ...
- java 数据结构与算法---栈
原理来自百度百科 一.栈的定义 栈是一种只能在一端进行插入和删除操作的特殊线性表:它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数 ...
- 5, java数据结构和算法: 栈 , 入栈, 出栈, 正序遍历,,逆序遍历
直接上代码: class ArrayStack{ //用数组模拟栈 int maxSize; int[] stack; int top = -1;//表示栈顶 public ArrayStack(in ...
- 【Java数据结构学习笔记之二】Java数据结构与算法之栈(Stack)实现
本篇是java数据结构与算法的第2篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型 栈是 ...
- java数据结构与算法之栈(Stack)设计与实现
本篇是java数据结构与算法的第4篇,从本篇开始我们将来了解栈的设计与实现,以下是本篇的相关知识点: 栈的抽象数据类型 顺序栈的设计与实现 链式栈的设计与实现 栈的应用 栈的抽象数据类型 栈是一种用于 ...
- Java数据结构和算法(一)--栈
栈: 英文名stack,特点是只允许访问最后插入的那个元素,也就是LIFO(后进先出) jdk中的stack源码: public class Stack<E> extends Vector ...
- Java数据结构和算法(六)——前缀、中缀、后缀表达式
前面我们介绍了三种数据结构,第一种数组主要用作数据存储,但是后面的两种栈和队列我们说主要作为程序功能实现的辅助工具,其中在介绍栈时我们知道栈可以用来做单词逆序,匹配关键字符等等,那它还有别的什么功能吗 ...
- Java数据结构和算法 - 二叉树
前言 数据结构可划分为线性结构.树型结构和图型结构三大类.前面几篇讨论了数组.栈和队列.链表都是线性结构.树型结构中每个结点只允许有一个直接前驱结点,但允许有一个以上直接后驱结点.树型结构有树和二叉树 ...
随机推荐
- POJ1456贪心(set或者并查集区间合并)
题意: 给你n商品,每个商品有自己的价值还有保质期,一天最多只能卖出去一个商品,问最大收益是多少? 思路: 比较好想的贪心,思路是这样,每一次我们肯定拿价值最大的,至于在那天拿 ...
- 10.PHP加密相关
PHP加密函数 <?php $str = 'This is an example!'; echo '1:'.$str.'<br>'; $crypttostr = c ...
- React-条件渲染
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...
- Day002 Java特性和优势
Java特性和优势 简单性(摒弃了c++的指针和内存分配释放) 面向对象(万物皆对象) 可移植性(write once run anywhere) 高性能 分布式 动态性(反射机制) 多线程 安全性 ...
- ColyseusJS 轻量级多人游戏服务器开发框架 - 中文手册(系统保障篇)
快速上手多人游戏服务器开发.后续会基于 Google Agones,更新相关 K8S 运维.大规模快速扩展专用游戏服务器的文章.拥抱️原生 Cloud-Native! 系列 ColyseusJS 轻量 ...
- Markdown编辑器怎么用
Markdown编辑器怎么用 1.代码块 快速创建一个代码块 // 语法: // ```+语言名称,如```java,```c++ 2.标题 语法:#+空格+标题名字,一个#表示一级标题,两个#表示二 ...
- Hive企业级性能优化
Hive作为大数据平台举足轻重的框架,以其稳定性和简单易用性也成为当前构建企业级数据仓库时使用最多的框架之一. 但是如果我们只局限于会使用Hive,而不考虑性能问题,就难搭建出一个完美的数仓,所以Hi ...
- 获取CPU频率
#include <stdio.h> #include <string.h> float get_cpu_clock_speed() { FILE *fp; char buff ...
- JS中函数定义和使用顺序
在js中如果定义函数是先声明函数,如: console.log(hello); //然后再去定义: function hello(){ alert("Hello");} 这种是可以 ...
- 从零搭建springboot服务02-内嵌持久层框架Mybatis
愿历尽千帆,归来仍是少年 内嵌持久层框架Mybatis 1.所需依赖 <!-- Mysql驱动包 --> <dependency> <groupId>mysql&l ...