中缀表达式转逆波兰表达式

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Stack;
import java.util.regex.Pattern;

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

    public static void main(String[] args) {
        ReversePoland reversePoland=new ReversePoland();
        String expressiong="((2+3)*45+13+2+4)/2";
        List<String> expList=reversePoland.reverExpression(expressiong);
        System.out.println(expList.toString());
        System.out.println(reversePoland.doCalc(expList));
    }
    public  Double doCalc(List<String> list){
        Double d = 0d;
        if(list == null || list.isEmpty()){
            return null;
        }
        if (list.size() == 1){
            System.out.println(list);
            d = Double.valueOf(list.get(0));
            return d;
        }
        ArrayList<String> list1 = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            list1.add(list.get(i));
            if(isoper(list.get(i))){
                Double d1 = doTheMath(list.get(i - 2), list.get(i - 1), list.get(i));
                list1.remove(i);
                list1.remove(i-1);
                list1.set(i-2,d1+"");
                list1.addAll(list.subList(i+1,list.size()));
                break;
            }
        }
        doCalc(list1);
        return d;
    }
    public  Double doTheMath(String s1,String s2,String symbol){
        Double result ;
        switch (symbol){
            case "+" : result = Double.valueOf(s1) + Double.valueOf(s2); break;
            case "-" : result = Double.valueOf(s1) - Double.valueOf(s2); break;
            case "*" : result = Double.valueOf(s1) * Double.valueOf(s2); break;
            case "/" : result = Double.valueOf(s1) / Double.valueOf(s2); break;
            default : result = null;
        }
        return result;

    }

    public List<String> reverExpression(String expresssion){
        List<String> data = Collections.synchronizedList(new ArrayList<String>());
        Stack<String> operStack=new Stack<>();
        int index=0;
       while(index<expresssion.length()){
           String ch=expresssion.substring(index,index+1);
           StringBuffer keepnum=new StringBuffer();
            if(opriority(ch)>0){
                while (true){
                    if(operStack.isEmpty()||"(".equals(operStack.peek())){
                        operStack.push(ch);
                        index++;
                        break;
                    }else if (opriority(ch)>opriority(operStack.peek())){
                        operStack.push(ch);
                        index++;
                        break;
                    }else {
                        String tmpOpe=operStack.pop();
                        data.add(tmpOpe);
                    }
                }
            }else if("(".equals(ch)){
                operStack.push(ch);
                index++;
            }else if(")".equals(ch)){
                while (true){
                    String tempope=operStack.pop();
                    if("(".equals(tempope)){
                        index++;
                        break;
                    }else {
                        data.add(tempope);
                    }
                }
            }else if(isNumber(ch)){
                keepnum.append(ch);
                while(index+1<expresssion.length()){
                    String nextStr=expresssion.substring(index+1,index+2);
                    if(isNumber(nextStr)){
                        keepnum.append(nextStr);
                        index++;
                    }else {
                        break;
                    }
                }
                index++;
                data.add(keepnum.toString());
            }else{
                try {
                    throw new Exception("包含非数字");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        Collections.reverse(operStack);
        data.addAll(new ArrayList<>(operStack));
        return data;
    }
    public Integer opriority(String oper){
        if("-".equals(oper)||"+".equals(oper)){
            return 1;
        }else if("*".equals(oper)||"/".equals(oper)){
            return 2;
        }else{
            return 0;
        }
      }

    public boolean isoper(String str){
        return "-".equals(str)||"+".equals(str)||"*".equals(str)||"/".equals(str);
    }
    public static boolean isNumber(String s){
        Pattern pattern = Pattern.compile("^[\\d]*$");
        return pattern.matcher(s).matches();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值