中缀表达式改为后缀表达式后计算值

步骤

  1. 初始化两个栈,运算符s1和存储结果的栈s2
  2. 从左到右扫描中缀表达式
  3. 遇到操作数时,压入s2
  4. 遇到运算符时,比较与其s1栈顶运算符的优先级
    1)如果s1为空,或栈顶运算符为左括号“*”,则直接将此运算符入栈
    2)否则,若优先级比栈顶的高,也将运算符压入栈s1
    3)否则,将s1的栈顶运算符弹出并压倒s2中再次转到 4.1与s1中新的栈顶运算符比较
  5. 若遇到括号
    1)遇到左括号“(”直接压入s1
    2)遇到右括号“)”一次弹出s1栈顶运算符,并压入s2 ,直到遇到左括号“(”,然后将这一对括号丢弃2
  6. 重复步骤2~5知到中缀表达式的最右边
  7. 将s1中剩余运算符一次弹出并压入s2
  8. 一次弹出s2的元素并输出 (其实s2只管压入并没有弹出过程 可以定义一个队列 或者一个list也可以的 )
  9. 这样就可以的到后缀表达式了 也叫逆波兰表达式
package com;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * 中缀表达式转换为后缀表达式之后在计算
 * 
 *
 *
 */
public class BoLan {
	public static void main(String[] args) {
		String yunsuan = "33+2-5*63/(5-1)";
		List<String> zhongZhui = toZhongZhui(yunsuan);
		System.out.println(zhongZhui);
		List<String> zhongZhuiToHouZhui = zhongZhuiToHouZhui(zhongZhui);
		System.out.println("后缀表达式是"  + zhongZhuiToHouZhui);
		int houZhui = houZhui(zhongZhuiToHouZhui);
		System.out.println("结果是" + houZhui);
	}
	
	/**
	 * 把算数表达式变为中缀
	 * @return
	 */
	public static List<String> toZhongZhui(String str) {
		List<String> list = new ArrayList<>();
		int i=0;
		String num = "";
		char c ;
		if(str==null||"".equals(str)) {
			return null;
		}
		do {
			c=str.charAt(i);
			if((c)<48||c>57) {
				//处理多位数的一种办法
//				if(!num.equals("")) {
//					list.add(num);
//					num = "";
//				}
				list.add(c+"");
				i++;
			}else {
				
				//处理多位数数字的另一种方法
				while(i<str.length()&&((c=str.charAt(i))>=48)&&((c=str.charAt(i))<=57)) {
					num+=c;
					i++;
				}
				list.add(num);
				num = "";
			}
			
		}while(i<str.length());
		return list;
	}
	
	/**
	 * 中缀转后缀
	 * @return
	 */
	public static List<String> zhongZhuiToHouZhui(List<String> list){
		List<String> houzhui = new ArrayList<>();
		Stack<String> sta = new Stack<>();
		for(String l:list) {
			if(l.matches("\\d+")) {
				houzhui.add(l);
			}else if(sta.size()==0||l.equals("(")) {
				sta.push(l);
			}else if(l.equals(")")){
				while(!sta.peek().equals("(")){
					houzhui.add(sta.pop());
				}
				sta.pop();
			}
			else  {
				while((!sta.isEmpty())&&youXianJi(l)<=youXianJi(sta.peek())) {
					houzhui.add(sta.pop());
				}
				sta.push(l);
			}
		}
		while(sta.size()!=0) {
			houzhui.add(sta.pop());
		}
		return houzhui;
	}
	/**
	 * 判断优先级
	 */
	public static int youXianJi(String str) {
		int a ;
		switch (str) {
		case "+":
			a = 1;
			break;
		case "-":
			a = 1;
			break;
		case "*":
			a = 2;
			break;
		case "/":
			a = 2;
			break;

		default:
			System.out.println("没有这个符号");
			a = -1;
			break;
		}
		return a;
	}
	
	/**
	 * 计算后缀
	 */
	public static int houZhui(List<String> list) {
		Stack<String> s = new Stack<>();
		for(String str:list) {
			if(str.matches("\\d+")) {
				s.push(str);
			}else {
				int num2 = Integer.parseInt(s.pop());
				int num1 = Integer.parseInt(s.pop());
				int temp;
				switch (str) {
				case "+":
					temp = num1+num2;
					break;
				case "-":
					temp = num1-num2;
					break;
				case "*":
					temp = num1*num2;
					break;
				case "/":
					temp = num1/num2;
					break;

				default:
					throw new RuntimeException("没有这个符号不能计算");
				}
				s.push(temp+"");
			}
		}
		return Integer.parseInt(s.pop());
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值