后缀表达式(逆波兰表达式)运算方法
- 从左向右读取表达式
- 遇到数字就压入栈中
- 遇到运算符就弹出栈顶和次顶元素。用 次顶元素 运算符 栈顶元素,并将运算结果压入栈中,直到栈为空,最终结果就是运算结果
设计
中缀表达式转后缀表达式
- 从左向右读取中缀表达式,并且创建 栈s1和 队列s2(因为s2只存不取且还要考虑出栈后逆序的问题,所以这里用队列来代替栈)
- 如果读到的元素的数字,就直接入队放入s2中
- 如果读到的是 运算符(运算符判定)
- 如果s1为空,则将该运算符压入s1
- 如果s1不为空
- 如果该运算符为 左括号,则直接压入s1
- 如果该运算符为 右括号,则将s1中的元素依次出栈并入队到s2中, 直到遇见左括号为止(括号不放入s2中)
- 如果该运算符的优先级 高于s1栈顶的运算符,则将该元素压入s1
- 如果该运算符的优先级 小于等于s1栈顶的运算符,则弹出s1栈顶的元素,并将其放入s2中,该运算符重 新判定入栈操作(运算符判定步骤)
- 如果中缀表达式已经读取完毕,则将s1中的元素依次出栈,放入s2中
- s2中的元素依次出队,该顺序即为后缀表达式
代码
java;collapse:true;;gutter:true;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;</p>
<p>public class PoiandNotation {
public static void main(String[] args) {
String expression = "1+((2+3)*4)-5";//定义一个中缀表达式
List infixExpressionList = toInfixExpressionList(expression);
System.out.println("中缀表达式的list="+infixExpressionList);
List suffixExpreesionList = parseSuffixExpreesionList(infixExpressionList);
System.out.println("后缀表达式的List="+suffixExpreesionList);</p>
<pre><code> System.out.println("expression的结果为: " + calculate(suffixExpreesionList));
}
/**
* 将中缀表达式转化为后缀表达式(逆波兰表达式)
* @param ls 传入的中缀表达式list集合
* @return
*/
public static List parseSuffixExpreesionList(List ls){
Stack s1 = new Stack<>();//用于暂存运算符
List s2 = new ArrayList<>();//用于存放逆波兰表达式,因为只存不取且还要考虑出栈后逆序的问题,所以这里用集合来代替栈
for (String item : ls){//循环遍历中缀表达式的每一个元素
if (item.matches("\\d+")){//多位数的情况直接入s2
s2.add(item);
}else if (item.equals("(")){
s1.push(item);
}else if (item.equals(")")){//碰到右括号时,s1一直出栈到s2里,直到碰到左括号为止
while (!s1.peek().equals("(")){
s2.add(s1.pop());
}
s1.pop();//取出左括号
}else {
while (s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item)){
//当s1栈顶运算符优先级大于或等于当前扫描到的运算符优先级,则出栈放入s2
s2.add(s1.pop());
}
s1.push(item);//把当前扫描到的运算符入栈到s1
}
}
//将s1剩余的运算符全部放入s2
while (s1.size() != 0){
s2.add(s1.pop());
}
return s2;
}
/**
* 将一个中缀表达式以集合的形式输入
* @param s 输入的中缀表达式
* @return
*/
public static List toInfixExpressionList(String s){
List ls = new ArrayList<>();
int i = 0;//用于扫描中缀表达式
char c;//把每一个扫描到的字符存到c里
String str;//用与拼接字符,存储多位数
do {
if ((c = s.charAt(i)) < 48 || (c = s.charAt(i)) > 57){//如果不是数字,就直接放入集合中
ls.add("" + c);
i++;
}else {
str = "";//初始化
while (i < s.length() && (c = s.charAt(i)) >= 48 && (c = s.charAt(i)) getSuffixList){
Stack stack = new Stack<>();
for (String item : getSuffixList) {
if (item.matches("\\d+")){//如果是数字就直接入栈
stack.push(item);
}else {
int num2 = Integer.parseInt(stack.pop());
int num1 = Integer.parseInt(stack.pop());
int res = 0;
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;
}
stack.push("" + res);
}
}
return Integer.parseInt(stack.pop());
}
</code></pre>
<p>}</p>
<p>//定义运算符的优先级
class Operation{
private static int ADD = 1;
private static int SUB = 1;
private static int MUL = 2;
private static int DIV = 2;</p>
<pre><code>public static int getValue(String operation){
int result = 0;
switch (operation){
case "+":
result = ADD;
break;
case "-":
result = SUB;
break;
case "*":
result = MUL;
break;
case "/":
result = DIV;
break;
default:
System.out.println("不存在该运算符");
break;
}
return result;
}
</code></pre>
<p>}
结果
Original: https://www.cnblogs.com/wyh518/p/16750841.html
Author: 腹白
Title: 用栈模拟计算器以及中缀转后缀表达式(逆波兰表达式)
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/622729/
转载文章受原作者版权保护。转载请注明原作者出处!