内容:掌握语法分析的基本思想,并用高级语言编写逆波兰式生成程序(4 学
时)
要求:利用逆波兰式生成算法编写程序,将从键盘上输入的算术表达式(中缀
表达式)转化成逆波兰式。
逆波兰表达式的生成过程涉及到运算符的优先级,下表中列出几个常用 运算 符的优先关系。
![](https://img-blog.csdnimg.cn/20210622135109222.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N4czEwNTEzMTAxMjM=,size_16,color_FFFFFF,t_70)
如上表所示的优先关系矩阵表示了+,-,*,/,↑,(,)等七种运算符之
间的相互优先关系。“>、<、=”三种符号分别代表“大于”、“小于”、“相
等”三种优先关系。左边的“=”与右边的“(”之间没有优先关系存在,所以表
中为空白。
逆波兰表达式生成算法的关键在于比较当前运算符与栈顶运算符的优先关
系,若当前运算符的优先级高于栈顶运算符,则当前运算符入栈,若当前运算符的
优先级低于栈顶运算符,则栈顶运算符退栈。
下面给出了逆波兰表达式生成算法的流程图。(为了便于比较相邻运算符的优
先级,需要设立一个工作栈,用来存放暂时不能处理的运算符,所以又称运算符栈)。
![](https://img-blog.csdnimg.cn/20210622135142144.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3N4czEwNTEzMTAxMjM=,size_16,color_FFFFFF,t_70)
代码:
import java.util.Scanner;
import java.util.Stack;
public class 逆波兰式生成程序 {
//输入运算符优先关系,存放不同级的符号优先级关系
static char[][] priorityTable = {
{'>', '>', '<', '<', '<', '<', '>'},
{'>', '>', '<', '<', '<', '<', '>'},
{'>', '>', '>', '>', '<', '<', '>'},
{'>', '>', '>', '>', '<', '<', '>'},
{'>', '>', '>', '>', '>', '<', '>'},
{'<', '<', '<', '<', '<', '<', '='},
{'>', '>', '>', '>', '>', ' ', '>'}
};
public static void main(String[] args){
postOrder();
}
public static void postOrder (){
//栈用以存放符号
Stack<Character> stack = new Stack<>();
//输入中缀表达式
System.out.println("输入中缀表达式:");
Scanner sc = new Scanner(System.in);
String strings = sc.nextLine();
System.out.println(strings);
System.out.println("逆波兰表达式:");
if (strings != null && strings.length() != 0 ) {
for (int i = 0; i < strings.length(); i++) {
char ch = strings.charAt(i);
stringEmpty(ch, stack);
if (i == strings.length() - 1) {
stackIsEmpty(stack);
System.out.println();
}
}
} else {
return;
}
}
//输入串不为空
public static void stringEmpty(char ch, Stack<Character> stack){
//判断是否是运算符
if (index(ch) == -1) {
System.out.print(ch);
}else if (stack.isEmpty()) { //入 栈
stack.push(ch);
return;
}else { //比较当前运算符于栈顶运算符的优先级
compare(ch, stack);
}
}
public static void stackIsEmpty(Stack<Character> stack) {
while (!stack.isEmpty()) {
System.out.print(stack.pop());
}
}
//比较当前运算符于栈顶运算符的优先级
public static void compare(char ch, Stack<Character> stack){
if (stack.isEmpty()) {
stack.push(ch);
} else {
char cmp = priorityTable[index(stack.peek())][index(ch)];
switch (cmp) {
case '<':
case '=':
stack.push(ch);
break;
case '>':
if (ch == ')') {
//当前运算符是')'
stackTop(stack);
} else {
System.out.print(stack.pop());
compare(ch, stack);
}
break;
default:
return ;
}
}
}
public static void stackTop(Stack<Character> stack){
if (stack.peek() == '('){
stack.pop();
} else if (stack.isEmpty()) {
System.out.println("error");
} else {
System.out.print(stack.pop());
stackTop(stack);
}
}
//给定字符串返回在优先级表中的索引
public static int index(char c) {
switch (c) {
case '+':
return 0;
case '-':
return 1;
case '*':
return 2;
case '/':
return 3;
case '↑':
return 4;
case '(':
return 5;
case ')':
return 6;
}
return -1; //代表数字
}
}
实验结果: