编译原理:实验二、逆波兰式生成程序

内容:掌握语法分析的基本思想,并用高级语言编写逆波兰式生成程序(4 学
           时)
要求:利用逆波兰式生成算法编写程序,将从键盘上输入的算术表达式(中缀
           表达式)转化成逆波兰式。
           逆波兰表达式的生成过程涉及到运算符的优先级,下表中列出几个常用             运算 符的优先关系。
如上表所示的优先关系矩阵表示了+,-,*,/,↑,(,)等七种运算符之
间的相互优先关系。“>、<、=”三种符号分别代表“大于”、“小于”、“相
等”三种优先关系。左边的“=”与右边的“(”之间没有优先关系存在,所以表
中为空白。
逆波兰表达式生成算法的关键在于比较当前运算符与栈顶运算符的优先关
系,若当前运算符的优先级高于栈顶运算符,则当前运算符入栈,若当前运算符的
优先级低于栈顶运算符,则栈顶运算符退栈。
下面给出了逆波兰表达式生成算法的流程图。(为了便于比较相邻运算符的优
先级,需要设立一个工作栈,用来存放暂时不能处理的运算符,所以又称运算符栈)。
代码:

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; //代表数字
	}
	
	
}

实验结果:

  • 3
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值