目录
一、后缀表达式举例
A:a+b的后缀表达式为ab+;
B:(a+b)*c-(a+b)/e的后缀表达式为ab+c*ab+e/-;
二、需求
A:输入一个后缀表达式,并用栈计算结果;
B:支持小括号和多位数整数;
三、字符串扫描法
-
思路分析
A:和之前的中缀表达式类似,对字符串自左到右扫描,定义一个数栈,用来存放扫描到的数字;
B:当扫描到运算符时,弹出数栈中两个元素,运算后再入栈;
C:重复A,B过程;
-
代码实现
package cn.itcast_03;
import java.util.Stack;
/*
*需求:
* A:输入一个后缀表达式(使用空格隔开),并用栈计算结果;
* B:支持小括号和多位数整数;
*分析:
* A:对字符串自左到右扫描,定义一个数栈,用来存放扫描到的数字;
* B:当扫描到运算符时,弹出数栈中两个元素,运算后再入栈;
* C:重复A,B过程;
*/
public class PolandNotation {
public static void main(String[] args) {
// 定义给逆波兰表达式
String expression = "3 4 + 5 * 6 -";// (3+4)*5-6
// 定义数栈
Stack<Integer> numStack = new Stack<Integer>();
// 定义相关变量
char ch = ' ';
String keepNum = "";
for (int i = 0; i < expression.length(); i++) {
ch = expression.substring(i, i + 1).charAt(0);
if (isOper(ch)) {
function(numStack, ch);
} else if (ch == ' ') {
continue;
} else {
// 是数字
keepNum += ch;
ch = expression.substring(i + 1, i + 2).charAt(0);
if (ch == ' ') {
numStack.push(Integer.parseInt(keepNum));
keepNum = "";
}
}
}
System.out.println(numStack.pop());
}
// 定义计算后出栈入栈功能
public static void function(Stack<Integer> numStack, char oper) {
int num1 = 0;
int num2 = 0;
int res = 0;
num1 = numStack.pop();
num2 = numStack.pop();
res = cal(num1, num2, oper);
numStack.push(res);
}
// 判断字符是否为运算符
public static boolean isOper(int ch) {
return ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')';
}
// 定义计算函数
public static int cal(int num1, int num2, char ch) {
int res = 0;
switch (ch) {
case '+':
res = num1 + num2;
break;
case '-':
res = num2 - num1;// 这个地方就想象2-1时的情景
break;
case '*':
res = num1 * num2;
break;
case '/':
res = num2 / num1;
break;
default:
break;
}
return res;
}
}
四、遍历ArrayList法
-
思路分析
A:将表示后缀表达式的字符串传递到ArrayList中;
B:通过遍历ArrayList,遇到数字则压入栈,遇到符号弹出栈中两个元素,并运算后,将结果入栈;
C:最后pop出栈中最后一个元素;
-
代码实现
package cn.itcast_03;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/*
*需求:
* A:输入一个后缀表达式(使用空格隔开),并用栈计算结果;
* B:支持小括号和多位数整数;
*分析:
* A:先将字符串中的字符放到ArrayList中
* B:将ArrayList传递给一个方法,遍历ArrayList,配合栈完成计算
*/
public class PolandNotation {
public static void main(String[] args) {
// 定义给逆波兰表达式
String expression = "3 4 + 5 * 6 - 2 1 / -";// (3+4)*5-6-(2/1)
List<String> rpnList = getListString(expression);
System.out.println("计算的结果为:" + calculate(rpnList));
}
// 将字符串中的字符放到ArrayList中
public static List<String> getListString(String expression) {
// 将字符串分割
String[] split = expression.split(" ");
List<String> list = new ArrayList<String>();
for (String ele : split) {
list.add(ele);
}
return list;
}
// 完成对后缀表达式的计算
public static int calculate(List<String> ls) {
// 创建一个栈
Stack<String> numStack = new Stack<String>();
// 遍历ls
for (String item : ls) {
// 使用正则表达式取出数字,\\d+表示多位数
if (item.matches("\\d+")) {
numStack.push(item);
} else {
function(numStack, item.charAt(0));
}
}
return Integer.parseInt(numStack.pop());
}
// 定义计算后出栈入栈功能
public static void function(Stack<String> numStack, char oper) {
int num1 = 0;
int num2 = 0;
int res = 0;
num1 = Integer.parseInt(numStack.pop());
num2 = Integer.parseInt(numStack.pop());
res = cal(num1, num2, oper);
numStack.push(res + "");
}
// 定义计算函数
public static int cal(int num1, int num2, char ch) {
int res = 0;
switch (ch) {
case '+':
res = num1 + num2;
break;
case '-':
res = num2 - num1;// 这个地方就想象2-1时的情景
break;
case '*':
res = num1 * num2;
break;
case '/':
res = num2 / num1;
break;
default:
break;
}
return res;
}
}