波兰逻辑学家的逆波兰表达式 思路
Posted 程序彤
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了波兰逻辑学家的逆波兰表达式 思路相关的知识,希望对你有一定的参考价值。
带小括号的中转后缀表达式:
1.初始化两个栈,运算符栈s1和中间结果栈s2
2.从左至右扫描中缀表达式
3.遇到数字时,将其压入s2
4.遇到运算符时,比较当前运算符与s1栈顶运算符的优先级:
①如果s1为空,或s1栈顶运算符为左括号(,则直接将此运算符入栈。
②否则,若优先级比栈顶运算符高,也将运算符压s1
③否则,将s1栈顶的运算符弹出并压入到s2中,再次从开始与s1中新的栈顶运算符相比较。
5.遇到括号时:
①如果是(,则直接压入s1.
②如果是),则依次弹出s1栈顶运算符并压入s2中直到遇到(为止。
6.重复2-5,直至结束。
7.将s1中剩余运算符弹出压入s2.
package 栈.数组模拟栈.中缀转后缀;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class PolandCalculator {
public static void main(String[] args) {
String input = "1+(2+3*4)-3";
List<String> list = infixToListparseSuf(input);
List<String> suffixList = parseSuffixExpressionListparseSuf(list);
int res = calculatePriority(suffixList);
System.out.println(res);
}
public static List<String> infixToListparseSuf(String input){
ArrayList<String> list = new ArrayList<>();
int i = 0;
String str = "";
char c;
do{
if ((c = input.charAt(i)) < 48 || (c = input.charAt(i)) > 57) { // 如果是运算符
list.add(""+c);
i++;
}else {
str = "";
while (i < input.length() && (c = input.charAt(i)) >= 48 && (c = input.charAt(i)) <= 57) {
str += c;
i++;
}
list.add(str);
}
}while (i<input.length());
return list;
}
/**
* 中缀转后缀
* @param list
* @return
*/
public static List<String> parseSuffixExpressionListparseSuf(List<String> list) {
Stack<String> stack = new Stack<>();
ArrayList<String> queue = new ArrayList<>();
for (String item : list) {
if (item.matches("\\\\d+")) { // 凡是遍历到数字就放到list中
queue.add(item);
}
if ("(".equals(item)) { // 凡是( 就压栈
stack.push(item);
}
if (")".equals(item)) {
while (!"(".equals(stack.peek())) { // 凡不是(也就是右括号就弹出栈顶运算符压入s2,直到遇到(为止。消除()括号
queue.add(stack.pop());
}
stack.pop();
}
if (!item.matches("\\\\d+")) {
// 如果当前运算符小于栈顶运算符优先级
while (stack.size() != 0 && Operation.getPriority(item) <= Operation.getPriority(stack.peek())) {
queue.add(stack.pop()); // 栈顶的优先级高必须先弹出去s2
}
stack.push(item);
}
}
while (stack.size() != 0) {
queue.add(stack.pop());
}
return queue;
}
/**
* 计算后缀表达式最终运算结果
* @param suffic
* @return
*/
public static int calculatePriority(List<String> suffic) {
Stack<String> stack = new Stack<>();
for (String item : suffic) {
if (item.matches("\\\\d+")) {
stack.push(item);
}
if (!item.matches("\\\\d+")) {
int num2 = Integer.parseInt(stack.pop());
int num1 = Integer.parseInt(stack.pop());
int res = 0;
if ("+".equals(item)) {
res = num1 + num2;
}
if ("-".equals(item)) {
res = num1-num2;
}
if ("*".equals(item)) {
res = num1*num2;
}
if ("/".equals(item)) {
res = num1/num2;
}
stack.push(""+res);
}
}
return Integer.parseInt(stack.pop());
}
}
class Operation {
public static int getPriority(String opert) {
int level = 0;
switch (opert) {
case "+":
level = 1;
break;
case "-":
level = 1;
break;
case "*":
level = 2;
break;
case "/":
level = 2;
break;
}
return level;
}
}
以上是关于波兰逻辑学家的逆波兰表达式 思路的主要内容,如果未能解决你的问题,请参考以下文章