数据结构(Java)——中缀表达式转后缀表达式

19 篇文章 0 订阅
本文详细介绍了如何将中缀表达式转换为后缀表达式,即逆波兰表达式。通过创建两个栈,一个用于存储运算符,另一个用于存储中间结果,遍历中缀表达式,根据运算符优先级规则进行处理,遇到括号时特殊处理。最终,将栈中剩余的运算符按顺序输出,得到后缀表达式。提供的Java代码示例展示了整个转换过程的关键步骤。
摘要由CSDN通过智能技术生成

中缀表达式转后缀表达式(逆波兰表达式)

表现形式

将中缀表达式转化成后缀表达式的样子是这样的:1+((2+3)*4)-5 ==> 1 2 3 + 4 * + 5 -

转化思路分析

思路如下:

1)先创建两个栈,一个放运算符S1,另一个放运算中间数 s2

这里提前说一下:由于后续的操作中S2栈中的数只有PUSH,没有POP,并且最后还要倒序输出一下,就由list来代替栈

2)从左到右遍历原中缀表达式

3)当遇到操作数的时候就直接将他pushS2

4)当遇到运算符时分一下几种情况:

​ ①当S1中没有运算符,或者栈顶是时,直接入栈s1

​ ②将运算符与S1栈顶的运算符进行比较,若该运算符的优先级小于等于栈顶运算符时,将S1的运算符pop出加入到S2中

​ ③如果该运算符的优先级大于栈顶运算符时,直接入栈S1

5)当遇到时分一下几种情况:

​ ①当为时,直接入栈S1

​ ②当为时,将S1的栈顶运算符POP出入栈S2,直到遇到停止,同时将S1清除掉

6)重复上述操作直到遍历完成

7)将S1的运算符依次POP出入栈S2

8)倒序输出S2中的数据即为后缀表达式

细节代码与关键之处

先将中缀表达式转化成list的形式,方便遍历

public static List<String> toInfixExpressionList(String s) {
		//定义一个List,存放中缀表达式 对应的内容
		List<String> ls = new ArrayList<String>();
		int i = 0; //这时是一个指针,用于遍历 中缀表达式字符串
		String str; // 对多位数的拼接
		char c; // 每遍历到一个字符,就放入到c
		do {
			//如果c是一个非数字,加入到ls
			if((c=s.charAt(i)) < 48 ||  (c=s.charAt(i)) > 57) {//通过asci表判断是否为数字
				ls.add("" + c);
				i++; //i需要后移
			} else { //如果是一个数,需要考虑多位数
				str = ""; //先将str 置成"" '0'[48]->'9'[57]
				while(i < s.length() && (c=s.charAt(i)) >= 48 && (c=s.charAt(i)) <= 57) {
					str += c;//拼接
					i++;
				}
				ls.add(str);
			}
		}while(i < s.length());
		return ls;//返回
	}

中缀转后缀

判断是数字还是
if(item.matches("\\d+")) {
				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弹出S2加入
				}
				s1.pop();//!!! 将 ( 弹出 s1栈, 消除小括号
			} 
当为运算符时
else {
				//当item的优先级小于等于s1栈顶运算符, 将s1栈顶的运算符弹出并加入到s2中,再次转到(4.1)与s1中新的栈顶运算符相比较
				//问题:我们缺少一个比较优先级高低的方法
				while(s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item) ) {
					s2.add(s1.pop());
				}
				//还需要将item压入栈
				s1.push(item);
			}
判断优先级的操作,(和上次的方法一样)
//编写一个类 Operation 可以返回一个运算符 对应的优先级
class Operation {
	private static int ADD = 1;
	private static int SUB = 1;
	private static int MUL = 2;
	private static int DIV = 2;
	
	//写一个方法,返回对应的优先级数字
	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("不存在该运算符" + operation);
			break;
		}
		return result;
	}
	
}

一定要注意 * 和 X

完整代码

public static List<String> parseSuffixExpreesionList(List<String> ls) {
		Stack<String> s1 = new Stack<String>(); // 符号栈
		List<String> s2 = new ArrayList<String>(); // 储存中间结果的Lists2
		//遍历ls
		for(String item: ls) {
			if(item.matches("\\d+")) {
				s2.add(item);
			} else if (item.equals("(")) {
				s1.push(item);
			} else if (item.equals(")")) {
				while(!s1.peek().equals("(")) {
					s2.add(s1.pop());
				}
				s1.pop();//!!! 将 ( 弹出 s1栈, 消除小括号
			} else {
				while(s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item) ) {
					s2.add(s1.pop());
				}
				s1.push(item);
			}
		}
		//对应7、8步
		while(s1.size() != 0) {
			s2.add(s1.pop());
		}
		return s2; 
	}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

痞子三分冷ゾジ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值