中缀表达式转后缀表达式

本文介绍了将中缀表达式如'1+((2+3)×4)-5'转换为后缀表达式的过程,详细阐述了算法步骤,包括初始化栈、遇到操作数和运算符时的处理、括号处理等。同时,展示了如何通过后缀表达式进行计算,给出了一段Java代码实现,最后展示了计算结果。整个过程涉及到了数据结构与算法在计算表达式中的应用。
摘要由CSDN通过智能技术生成

体步骤如下:

1)初始化两个栈:运算符栈s1和储存中间结果的栈s2;
2)从左至右扫描中缀表达式;
3)遇到操作数时,将其压s2;
4)遇到运算符时,比较其与s1栈顶运算符的优先级:
             (1)如果s1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
             (2)否则,若优先级比栈顶运算符的高,也将运算符压入s1;
             (3)否则,将s1栈顶的运算符弹出并压入到s2中,再次转到(4-1)与s1中新的栈顶运算符相比较;
5)遇到括号时:
              (1) 如果是左括号“(”,则直接压入s1
              (2) 如果是右括号“)”,则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃
6)重复步骤2至5,直到表达式的最右边
7)将s1中剩余的运算符依次弹出并压入s2
8)依次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式

中缀表1+((2+3)×4)-5”为后缀表达式的

扫描到的元素

s2(栈底->栈顶)

s1 (栈底->栈顶)

说明

1

1

数字,直接入栈

+

1

+

s1为空,运算符直接入栈

(

1

+ (

左括号,直接入栈

(

1

+ ( (

同上

2

1 2

+ ( (

数字

+

1 2

+ ( ( +

s1栈顶为左括号,运算符直接入栈

3

1 2 3

+ ( ( +

数字

)

1 2 3 +

+ (

右括号,弹出运算符直至遇到左括号

×

1 2 3 +

+ ( ×

s1栈顶为左括号,运算符直接入栈

4

1 2 3 + 4

+ ( ×

数字

)

1 2 3 + 4 ×

+

右括号,弹出运算符直至遇到左括号

-

1 2 3 + 4 × +

-

-+优先级相同,因此弹出+,再压入-

5

1 2 3 + 4 × + 5

-

数字

到达最右端

1 2 3 + 4 × + 5 -

s1中剩余的运算符

结果"1 2 3 + 4 × + 5 –"

package com.wang;

import java.util.*;

public class Test {

	public static void main(String[] args) {
		
		//中缀表达式
		String exp="1+((2+3)*4)-5";
		List<String> inlist=toExp(exp);
		System.out.println("中缀表达式: "+inlist);
		//对应的后缀表达式
		List<String> parseList = parseList(inlist);
		System.out.println("对应的后缀表达式: "+parseList);
		
		
		/*String Poland="3 4 + 5 * 6 -";
		//先将表达式存入Arralist,遍历Arralist配合栈完成计算
		List<String> getlist = getlist(Poland);
		System.out.println(getlist);*/
		int res=compute(parseList);
		System.out.println("结果: "+res);
	}
	
	
	public static List<String> getlist(String Poland) {
		//按空格分割字符串并存入数组
		String[] split = Poland.split(" ");
		ArrayList<String> arrayList = new ArrayList<String>();
		
		//遍历数组存入集合
		for (String i :split) {
			arrayList.add(i);
		}
		return arrayList;
	}
	
	
	public static int compute(List<String> list) {
		Stack<String> stack=new Stack<String>();
		for (String i : list) {
			//使用正则表达式取出多位数字
			if (i.matches("\\d+")) {
				//入栈
				stack.push(i);
			}else {
				//取出两个运算后入栈
				int num2=Integer.parseInt(stack.pop());
				int num1=Integer.parseInt(stack.pop());
				int res=0;
				if(i.equals("+")) {
					res=num1+num2;
				}else if (i.equals("-")) {
					res=num1-num2;
				}else if (i.equals("*")) {
					res=num1*num2;
				}
				else if (i.equals("/")) {
					res=num1/num2;
				}
				stack.push(res+"");
			}
		}
		return Integer.parseInt(stack.pop());
	}
	
	
	
	//将中缀表达式存入集合 也就是转成1,+,(,(,2,+,3,),*,4,),-,5
	public static List<String> toExp(String s){
		ArrayList<String> ls = new ArrayList<String>();
		//用于遍历中缀字符串
		int i=0;
		//用于拼接多位数
		String str;
		//每遍历一位就放进c里
		char c;
		do {
			//如果它是一个字符就加入ls
			if((c=s.charAt(i))<48||(c=s.charAt(i))>59) {
				ls.add(""+c);
				i++;
			}else {
				//如果是一个数,则需要考虑是否多位数
				
				//每次拼接前重置str
				str="";
				while (i<s.length()&&(c=s.charAt(i))>=48&&(c=s.charAt(i))<=59) {
					str+=c;
					i++;
				}
				ls.add(str);
			}
		} while (i<s.length());
		return ls;
	}
	
	
	//将得到的中缀表达式分成两部分
	//存入符号栈和中间结果栈
	public static List<String> parseList(List<String> ls){
		//符号栈
		Stack<String> s1 = new Stack<String>();
		//中间结果栈
		ArrayList<String> s2 = new ArrayList<String>();
		
		for (String s : ls) {
			//如果是一个数就加入ls1
			if (s.matches("\\d+")) {
				s2.add(s);
			}else if (s.equals("(")) {
				s1.push(s);
			}else if (s.equals(")")) {
				//如果是右括号则依次弹出s1栈顶的运算符,压入s2,直到遇到左括号为止
				while (!s1.peek().equals("(")) {
					s2.add(s1.pop());
				}
				//将括号弹出消除
				s1.pop();
			}else {
				while(s1.size()!=0&&Oper.getv(s1.peek())>=Oper.getv(s)) {
					s2.add(s1.pop());
				}
				s1.push(s);
			}
		}
		
		//将s1中剩余的运算符依次弹出并加入s2
		while(s1.size() != 0 ) {
			s2.add(s1.pop());
		}
		return s2;
	}
	
}
class Oper{
	private static int ADD=1;
	private static int SUB=1;
	private static int MUL=1;
	private static int DIV=1;
	
	public static int getv(String oper) {
		int su=0;
		switch (oper) {
		case "+":
			su=ADD;
			break;
		case "-":
			su=SUB;
			break;
		case "*":
			su=MUL;
			break;
		case "/":
			su=DIV;
			break;
		}
		return su;
	}
}

 

package com.wang;

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



public class AllPoland {

	public static void main(String[] args) {
		//举例1: 2 + (3-4) => 2 3 4 - +
	 	//举例2: 4 * 5 - 8 + 60 + 8 / 2 = 4 5 * 8 - 60 + 8 2 / + 
	 	//举例3: (3+4)×5-6 => 3 4 + 5 * 6 -
		//String suffixExperss = "4 5 * 8 - 60 + 8 2 / +";
		//String suffixExperss = "2 3 4 - +";
//		String suffixExperss = "3 4 + 5 * 6 -";
//		
		ReversePolishCal reversePolishCal = new ReversePolishCal();
//		
//		List <String> suffixExpressionList = reversePolishCal.getListBySuffixExpression(suffixExperss);
//		
//        System.out.println("计算结果:"+ reversePolishCal.calculate(suffixExpressionList));
        
        //测试输入中缀表达式是否能计算成功
        String infixExpression = "4*5-8+60+8/2";
        
       
        List<String> infixExpressionList = reversePolishCal.toInfixExpression(infixExpression);
        List<String> suffixExpressionList2 = reversePolishCal.parseSuffixExpression(infixExpressionList);
        //输出后缀表达式
        for(String ele : suffixExpressionList2) {
        	System.out.print(ele + " ");
        }
        System.out.println();
        //输出结果
        System.out.println("计算结果:"+ reversePolishCal.calculate(suffixExpressionList2));
        
        
	}

}

class ReversePolishCal {
	
	/**
     * 把字符串转换成中序表达式 : 比如 2+(3-4), 并放入到List中
     * @param s
     * @return
     */
    public List<String> toInfixExpression(String infixExpression) {
        List<String> ls = new ArrayList<String>();//存储中序表达式
        int i = 0;
        String str;
        char c;
        do {
        	//如果c 在 < 48 或者 > 57 说明是符号, 这里没有判断是 + , - , * , / 等等
            if ((c = infixExpression.charAt(i)) < 48 || (c = infixExpression.charAt(i)) > 57) {
                ls.add("" + c);
                i++;
            } else { // 说明是数字,要进行拼接处理
                str = "";
                while (i < infixExpression.length() && (c = infixExpression.charAt(i)) >= 48
                        && (c = infixExpression.charAt(i)) <= 57) {
                    str += c;
                    i++;
                }
                ls.add(str);
            }

        } while (i < infixExpression.length());
        return ls;
    }
    
    /**
     * 将一个中缀表达式对应的List 转成 转换成逆波兰表达式, 放入到List中
     * @param ls
     * @return
     */
    public  List<String> parseSuffixExpression(List<String> ls) {
        Stack<String> s1=new Stack<String>();
        Stack<String> s2=new Stack<String>();
        List<String> lss = new ArrayList<String>();
        for (String ss : ls) {
            if (ss.matches("\\d+")) {
                lss.add(ss);
            } else if (ss.equals("(")) {
                s1.push(ss);
            } else if (ss.equals(")")) {

                while (!s1.peek().equals("(")) {
                    lss.add(s1.pop());
                }
                s1.pop();
            } else {
                while (s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(ss)) {
                    lss.add(s1.pop());
                }
                s1.push(ss);
            }
        }
        while (s1.size() != 0) {
            lss.add(s1.pop());
        }
        return lss;
    }
	
	
	
	//将一个后缀表达式,依次放入到List<String>中
	public List<String> getListBySuffixExpression(String suffixExpression) {
		String[] split = suffixExpression.split(" ");
		List<String> list = new ArrayList<String>();
		for (String element : split) {
			list.add(element);
		}
		return list;
	}
	
	/**
	 * 
	 * @param ls 是一个按照逆波兰表达式得到衣蛾List 
	 * @return
	 */
    public int calculate(List<String> ls) {
    	Stack<String> s=new Stack<String>();
        for (String str : ls) {
            if (str.matches("\\d+")) {
                s.push(str);
            } else {
                int b = Integer.parseInt(s.pop());
                int a = Integer.parseInt(s.pop());
                int result=0;
                if (str.equals("+")) {
                    result = a + b;
                } else if (str.equals("-")) {
                    result = a - b;
                } else if (str.equals("*")) {
                    result = a * b;
                } else if (str.equals("/")) {
                    result = a / b;
                } else {
                	throw new RuntimeException("符号错误");
                }
                s.push("" + result);
            }
        }
        //System.out.println(s.peek()); 
        return Integer.parseInt(s.pop());
    }
	
	
}


class Operation {
    private static int ADDITION=1;
    private static int SUBTRACTION=1;
    private static int MULTIPLICATION=2;
    private static int DIVISION=2;

    public static int getValue(String operation){
        int result;
        switch (operation){
            case "+":
                result=ADDITION;
                break;
            case "-":
                result=SUBTRACTION;
                break;
            case "*":
                result=MULTIPLICATION;
                break;
            case "/":
                result=DIVISION;
                break;
            default:
//                System.out.println("不存在该运算符");
                result=0;
        }
        return result;
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

1while(true){learn}

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

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

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

打赏作者

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

抵扣说明:

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

余额充值