/*
- 对于输入的逆波兰表达式(后缀表达式)操作的原则如下:
- 1、创建一个栈stack的对象,用来存储从后缀表达式中读取到的数
- 2、处理逆波兰表达式:
- 2.1从左至右扫描表达式,如果遇到 数字,就将数字压入堆栈;
- 如果遇到 运算符,就从数栈中pop()出来栈顶元素、次顶元素:num1、num2。
- 进行相应运算,并将运算的结果压入数栈
- 2.2扫描到expression的最右端时,数栈中保存的数,就是最终的结果
*/
/*
* 处理的思路为:
* 1、将expression先转化为对应的list,方便后面逐项读取的时候 的遍历
* 1.1 注意的是:由于expression中不同的元素是通过" "(空格)分开的,
* 所以在进行expression到list的转换的过程中,是需要 滤除空格 的,
* 使用的方法是:string类的split()
* 1.2 另一点需要注意的地方是:在1.1的滤除空格的操作过程中,返回的是一个string[],
* 在实现string[]向ArrayList的转换的过程中,最好不要使用Arrays.asList(),
* 因为该方法存在局限性,返回的是一个Arrays的内部类的对象,并不是真正的一个 ArrayList的对象,
* 因为返回的对象所属的类(所谓的假的“ArrayList”),并没有重写remove()、add()等方法,只可以实现get(),
* 并且,对于基本数据类型的数组不友好
* ------使用增强for循环,可以实现,将过滤后得到的string[]转换为 集合ArrayList
* 2、对于expression调整得到的list,进行遍历,并且结合堆栈,完成运算calculation
* 2.1 注意的是:在进行判断 集合中的元素是数字(包含多位数的情况)还是运算符的时候,是可以使用正则表达式
* 对应的是string类的matches(regex)方法,其中的regex表示:正则表达式
*/
package com.athanchang.java;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
//直接输入一个逆波兰表达式,进行相应处理
public class PolandNotation {
public static void main(String[] args) {
//举例为:1+((2+3)*4)-5=16
String expression = "3 4 + 5 * 6 -";
//方法:将expression先转化为对应的list,方便后面逐项读取的时候 的遍历
List<String> list = getStringList(expression);
System.out.println(list);
//对于expression调整得到的list,进行遍历,并且结合堆栈,完成运算calculation
int calcultation = calcultation(list);
System.out.println(calcultation);
}
//方法:将expression先转化为对应的list,方便后面逐项读取的时候 的遍历
public static List<String> getStringList(String s){
//先对于传入的string进行 滤除空格 的操作
String[] split = s.split(" ");
//创建一个ArrayList对象,作为转化后的数据的存储载体
ArrayList<String> list = new ArrayList<String>();
//使用增强for循环,将split中的数据add到list中
for(String item : split) {
list.add(item);
}
return list;
}
//对于expression调整得到的list,进行遍历,并且结合堆栈,完成运算calculation
public static int calcultation(List<String> ls) {
//创建一个堆栈的对象,在计算过程存储数字,也称为数栈
Stack<String> stack = new Stack<String>();
/*
* 开始对ls进行遍历,具体的操作为:
* 如果遇到 数字,就将数字压入堆栈;
* 如果遇到 运算符,就从数栈中pop()出来栈顶元素、次顶元素:num1、num2。
* 进行相应运算,并将运算的结果压入数栈
*/
for (String item : ls) {
// 如果是数字(多位数),直接入 数栈
if (item.matches("\\d+")) {// 是多位数
stack.push(item);
} else {
/*
* 是运算符
* 出栈2个元素:栈顶元素、次顶元素
*/
//定义一个变量,暂存每次计算的结果值;并在最终,将最终的结果值赋给他
int num2 = Integer.parseInt(stack.pop());// 栈顶元素
int num1 = Integer.parseInt(stack.pop());// 次顶元素
int res = 0;
// 根据当前的item的运算符类型,进行相应的计算
// if (item.equals("+")) {
// res = num1 + num2;
// } else if (item.equals("-")) {
// res = num1 - num2;
// } else if (item.equals("*")) {
// res = num1 * num2;
// } else if (item.equals("/")) {
// res = num1 / num2;
// } else {
// throw new RuntimeException("输入的运算符有误!");
// }
switch (item) {
case "+":
res = num1 + num2;
break;
case "-":
res = num1 - num2;
break;
case "*":
res = num1 * num2;
break;
case "/":
res = num1 / num2;
break;
default:
throw new RuntimeException("输入的运算符有误!");
}
stack.push(res + "");//因为res是int类型的,转换为string类型的才可以入栈
}
}
return Integer.parseInt(stack.pop());
}
}