java代码实现中缀表达式转换为后缀表达式

本文介绍了如何使用Java将中缀表达式转换为后缀表达式,并通过栈操作进行计算。示例中展示了具体代码实现,包括中缀表达式转list、后缀表达式转换、后缀表达式计算等关键步骤。
## java代码实现中缀表达式转换为后缀表达式
实现思路:

在这里插入图片描述

package com.stack;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class PolandNotation {
	public static void main(String[] args) {
		//完成将一个中缀表达式转换成后缀表达式的功能
		//说明
		//1. 1+((2+3)*4)-5转换成 1 2 3 + 4 * + 5 -
		//2.因为直接对字符串进行操作不方便,所以先将字符串转成一个中缀的list
		// 即 1+((2+3)*4)-5转化成ArrayList[1,+,(,(,2,+,3,*,4,),-,5]
		//3.将中缀表达式对应的list转换成后缀表达式对应的list
		//	即ArrayList[1,+,(,(,2,+,3,*,4,),-,5]得到结果ArrayList[1,2,3,+,4,*,+,5,-]
		String expression = "1+((2+3)*4)-5";
		List<String> infixExpressionList =  toInfixExpressionList(expression);
		System.out.println("中缀表达式对应的list="+infixExpressionList);//ArrayList[1,+,(,(,2,+,3,*,4,),-,5]
		List<String> SuffixExpressionList  = parseSuffixExpressionList(infixExpressionList);
		System.out.println("后缀表达式对应的List=" + SuffixExpressionList);
		System.out.printf("expression=%d",calculate(SuffixExpressionList));
	/*	//先定义一个逆波兰表达式
		//(3+4)+5×6 => 3 4 + 5 × 6 -
		//为了方便,逆波兰表达式的数字和符号用空格隔开
		String suffixExpression = "3 4 + 5 * 6 -";
		//1.先将3 4 + 5 × 6 -  放到ArrayList中
		//2.将ArrayList传给一个方法,遍历ArrayList,配合栈,完成计算
		List<String> list = getListString(suffixExpression);
		System.out.println("list =" + list);
		int res = calculate(list);
		System.out.println("计算的结果是="+res);*/
	}
	//方法:将中缀表达式转换成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){
				 ls.add(""+c);
				 i++;//i需要后移
				 
			}else{//如果c是一个数字,需要考虑多位数问题
				str = "";//先将str置成空串
				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;//
	}
//	即ArrayList[1,+,(,(,2,+,3,*,4,),-,5]得到结果ArrayList[1,2,3,+,4,*,+,5,-]
	//方法:将中缀表达式对应的list转换成后缀表达式对应的list
	public static List<String> parseSuffixExpressionList(List<String> ls){
		//定义两个栈
		Stack<String> s1 = new Stack<String>();//符号栈
		//因为s2在整个转换过程中,没有pop操作,而且最后需要逆序输出,
		//为了省事,我们不使用Stack<String>而直接使用List<String> s2
		//Stack<String> s2 = new Stack<String>();//存储中间结果的栈s2
		List<String> s2 = new ArrayList<String>();
		//遍历ls
		for(String item : ls){
			//如果是一个数就加入到s2
			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.pop();//将小括号弹出s1,消除括号
			}else{
				//当item的优先级小于等于s1栈顶的运算符优先级,将s1栈顶的运算符弹出并加入到s2中,再次转到   与s1中新的栈顶运算符相比较
				//缺少比较优先级高低的方法
				while(s1.size()!=0 && Operation.getValue(s1.peek())>=Operation.getValue(item)){
					s2.add(s1.pop());
				}
				//还需要将item压入栈中
				s1.push(item);			}
		}
		//将s1剩余的运算符依次弹出并压入s2
		while(s1.size()!=0){
			s2.add(s1.pop());
		}
		return s2;//因为是存放到一个list中,所以按顺序输出就是对应的后缀表达式对应的List
	}
	//将一个逆波兰表达式,依次将数据和运算符放入到ArrayList中
	public static List<String> getListString(String suffixExpression){
		//将suffixExpression分割
		String[] split = suffixExpression.split(" ");
		List<String> list = new ArrayList<String>();
		for(String ele:split){
			list.add(ele);
		}
		return list;
	}
	//完成对逆波兰表达式的运算
//	1.从做往右扫描,将3和4压入堆栈
//	2.遇到+运算符,因此弹出4和3(4为栈顶元素,3为次顶元素),计算3+4的值,得7,再将7入栈
//	3.将5入栈
//	4.接下来是×运算,因此弹出5和7,计算出7×5=35,将35入栈
//	5.将6入栈
//	6.最后是-运算符,计算出35-6=29,由此得出最终结果
	public static int calculate(List<String> ls){
		//创建栈,只需要一个栈
		Stack<String> stack = new Stack<String>();
		//遍历ls
		for(String item:ls){
			//使用正则表达式来取出数
			if(item.matches("\\d+")){//匹配的是多位数
				//入栈
				stack.push(item);
			}else{
				//pop出两个数,并运算,再入栈
				int num2 =Integer.parseInt(stack.pop()) ;
				int num1 = Integer.parseInt(stack.pop());
				int res = 0;
				if(item.equals("+")){
					res = num1 + num2;
				}else if(item.equals("-")){
					res = num1-num2;
				}else if(item.equals("*")){
					res = num1*num2;
				}else if(item.equals("/")){
					res = num1/num2;
				}else{
					throw new RuntimeException("运算符有误");
				}
				//把res入栈
				stack.push(res+"");
			}
		}
		//最后留在stack中的数据就是运算结果
		return Integer.parseInt(stack.pop());
	}
}
//编写一个类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("不存在该运算符");
			break;
		}
		return result;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

江小白用户

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

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

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

打赏作者

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

抵扣说明:

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

余额充值