目录 :
1.二者区别:
1.中缀表达式:1 + 2 / 3 ( 3 * 2 + 1 ) / 5
2.后缀表达式:1 2 3 / + 3 2 * 1 + 5 /
划重点:后缀表达式将算术运算符的2个操作数放在该运算符之前,后缀表达式同时也表示了计算的顺序
2.转换的具体做法:
使用 栈
来操作
- 首先创建一个
操作符栈
- 将中缀表达式
格式化
,便于提取有效字符 扫描整个中缀表达式,按照下面的
规则
进行:
1.数字直接输出
2.左括号'('入栈
3.遇到右括号')',将栈中所有的符号出栈输出直到遇到左括号'(',最后将左括号出栈
4.其他符号(+、-、*、/),将栈中优先级大于等于当前符号的出栈, 直到遇到比当前符号优先级更低的符号或者'('或者栈空,将当前符号入栈。最后,将栈中剩余的符号输出
3.计算的原理:
后缀表达式表示了计算的顺序,这里需要一个操作数栈
1.扫描后缀表达式
2.将数字入栈
3.遇到符号(+、-、*、/),弹出2个操作数,计算结果,然后将结果入栈
4.最后循环结束后,将栈中唯一的数字弹出即为结果
这里就不举列子了
4.举个例子:
( 3 * 2 + 1 ) / 5
- ( 入栈
操作符栈:(
输出:
- 3 输出
操作符栈:(
输出:3
- *执行规则4,
操作符栈:( *
输出:3
- 2 输出
操作符栈:( *
输出:3 2
- +执行规则4
操作符栈:( +
输出:3 2 *
- 1 输出
操作符栈:( +
输出:3 2 * 1
- 遇到右括号,执行规则3
操作符栈:
输出:3 2 * 1 +
- / 执行规则4
操作符栈:/
输出:3 2 * 1 +
- 最后,将栈中剩余的符号输出
操作符栈:
输出:3 2 * 1 + /
5.代码:
PS:重点理解规则4的实现,我在这里卡了好久,虽然有点简单。还有就是一定注意格式化的具体做法。(⊙o⊙)…,这个代码敲了2晚上,继续加油吧!o(╥﹏╥)o改了4遍了,大哥大姐点个赞吧。
import java.util.Scanner;
import java.util.Stack;
// 中缀表达式转为后缀表达式
public class InfixToPostfix {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入一个中缀表达式:");
String[] infix = formatInput(input.nextLine());// 输入格式化
Stack<Character> operation = new Stack<>();// 操作符栈
String postfix = "";// 后缀表达式,String
for (String s : infix) {
if (s.length() == 0)// 因为格式化后会多了无效的空格,在运算时忽略
continue;
// 其他符号(+、-、*、/),将栈中优先级大于等于当前符号的出栈, 直到遇到比当前符号优先级更低的符号或者'('或者栈空,将当前符号入栈。
else if (s.charAt(0) == '+' || s.charAt(0) == '-' || s.charAt(0) == '*' || s.charAt(0) == '/') {
while (!operation.isEmpty() && operation.peek() != '(') {
if (priorityIsBiggerOrTheSame(operation.peek() + "", s))// 将优先级大于等于自己的符号出栈输出
postfix += operation.pop() + " ";
else
break;// 如果遇到优先级小的符号,循环终止
}
operation.push(s.charAt(0));// 当前符号入栈
}
else if (s.charAt(0) == '(')// 左括号'('入栈
operation.push(s.charAt(0));
else if (s.charAt(0) == ')') {// 右括号')',将栈中的符号除了左括号'('全部出栈
while (operation.peek() != '(')
postfix += operation.pop() + " ";
operation.pop();
}
else// 最后,将数字输出,放在最后,可以不用判断字符串s为数字
postfix += s + " ";
}
while (!operation.isEmpty())// 将剩余符号全部出栈输出
postfix += operation.pop() + " ";
System.out.println("后缀表达式:" + postfix);
System.out.println("结果是:" + compute(postfix.split(" ")));
}
// 格式化中缀表达式输入,即在符号前后添加空格,便于后面的分隔操作
public static String[] formatInput(String s) {
String temp = "";
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '+' || c == '-' || c == '*' || c == '/')
temp += " " + c + " ";
else
temp += c;// 数字不用加空格
}
return temp.split(" ");// 分割
}
// 计算后缀表达式的结果,将数字入栈,遇到符号,弹出2个数字运算,将结果入栈
public static int compute(String[] postfix) {
Stack<Integer> value = new Stack<>();
for (String s : postfix) {
char c = s.charAt(0);
if (c == '+' || c == '-' || c == '*' || c == '/') {
int v1 = value.pop();
int v2 = value.pop();
switch (c) {
case '+':
value.push(v2 + v1);
break;
case '-':
value.push(v2 - v1);
break;
case '*':
value.push(v2 * v1);
break;
case '/':
value.push(v2 / v1);
break;
}
}
else
value.push(Integer.parseInt(s));
}
return value.pop();
}
// 优先级判断,a是否大于b
public static boolean priorityIsBiggerOrTheSame(String a, String b) {
String s = "+- */";
return (s.indexOf(a) - s.indexOf(b)) >= 2;
}
}
5.结果截图: