简易逆波兰计算器

package com.stack;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
//逆波兰计算器
/*
* 计算器主要方法:1计算器中缀转后缀
*                  思路:
*                     遍历中缀表达式集合
*                        如果是数字直接放到集合
*                        如果是运算符:
*                            1判断栈是否为空或者栈顶为左括号,直接入栈
*                            2如果栈不为空,且该运算符优先级高于栈顶优先级,直接入栈
*                            3如果该运算符优先级小于等于栈顶优先级,将栈顶元素抛出放至集合中,循环此操作,直至高于栈顶元素优先级或栈为空,将此运算符放入栈中
*                        如果是左括号,直接入栈
*                        如果是右括号,将栈中元素抛出放至集合,直至栈顶元素为左括号,左括号抛出不入栈
*                     遍历结束:栈中剩余元素依次弹出放至集合
*               2 计算后缀表达式
*                    遍历后缀表达式
*                    遇到数字直接入栈
*                    遇到运算符抛出两个栈顶元素运算后结果入栈
*                    循环此操作,直至集合为空,栈中剩余一个元素为结果
* */
public class Calculator {
    //获取运算符优先级
    public int getPriority(String param){
        if("+".equals(param)||"-".equals(param)){
            return 0;
        }
        if("/".equals(param)||"*".equals(param)){
            return 1;
        }
        return -1;
    }
    //判断是否位数字
    public boolean isNumber(String param){
        return param.matches("\\d+");
    }
    //判断是否为操作符
    public boolean isOperator(String param){
        return  "+".equals(param)||"-".equals(param)||"*".equals(param)||"/".equals(param);
    }
    //字符串转中缀表达式(此方法只支持一位整数,如果想要多位小数或整数可以在此方法添加判定方式)
    public List toList(String param){
        List<String> list=new ArrayList<>();
        int index=0;
        while(index<=param.length()-1){
            list.add(param.substring(index,index+1));
            index++;
        }
        return list;
    }
    //中缀表达式转后缀表达式
    public List toSuffixList(List<String> list){
        //栈用来临时存储字符
        Stack<String> stack=new Stack<>();
        //集合用于存放中缀表达式
        List<String> suffixList=new ArrayList<>();
        for(String item: list){
            //如果是数字
            if(isNumber(item)){
                suffixList.add(item);
            }
            //如果是运算符
            if(isOperator(item)){
                //如果栈为空或者字符是左括号
                if(stack.isEmpty()||"(".equals(stack.peek())){ stack.push(item);}
                //如果栈不为空
                else{
                    while (!stack.isEmpty()){
                        //如果此字符优先级比栈顶高,直接入栈
                        if(getPriority(item)>getPriority(stack.peek())){break;}
                        //如果字符优先级没有比栈顶高
                        if(getPriority(item)<=getPriority(stack.peek())){
                            //弹出栈顶元素放入集合
                            suffixList.add(stack.pop());
                        }
                    }
                    //运算符入栈
                    stack.push(item);
                }

            }
            //如果是左括号
            if("(".equals(item)){
                stack.push(item);
            }
            //如果是右括号
            if(")".equals(item)){
                //弹出栈中数据,直至碰到左括号
                while (!stack.peek().equals("(")){
                    suffixList.add(stack.pop());
                }
                //弹出左括号
                stack.pop();
            }
        }
        //遍历完毕中缀表达式,将栈中数据依次弹出放至集合
        while(!stack.isEmpty()){
            suffixList.add(stack.pop());
        }
        return suffixList;
    }
    //使用后缀表达式计算运算结果
    public String Calculate(List<String> suffixList){
        //栈用来临时存放数据
        Stack<String> stack=new Stack<>();
        for(String item: suffixList){
            if(isNumber(item)){
                stack.push(item);
            }
            //遇见运算符从栈中弹出两个数字进行运算后放入栈中
            if(isOperator(item)){
                if("+".equals(item)){
                    stack.push(""+(Double.valueOf(stack.pop())+Double.valueOf(stack.pop())));
                }
                if("-".equals(item)){
                    double top1= Double.parseDouble(stack.pop());
                    double top2= Double.parseDouble(stack.pop());
                    stack.push(""+(top2-top1));
                }
                if("*".equals(item)){
                    stack.push(""+(Double.valueOf(stack.pop())*Double.valueOf(stack.pop())));
                }
                if("/".equals(item)){
                    double top1= Double.parseDouble(stack.pop());
                    double top2= Double.parseDouble(stack.pop());
                    //格式化结果,保留两位小数
                    DecimalFormat decimalFormat=new DecimalFormat("#.00");
                    double result= Double.parseDouble(decimalFormat.format(top2/top1));

                    stack.push(""+result);
                }
            }
        }
        //栈中最后一个元素为结果
        return stack.pop();
    }
}

测试:

    @Test
    public void test(){
       Calculator calculator=new Calculator();
       String a="1+((2+3)*4)/6";
        System.out.println(calculator.toList(a));
        System.out.println(calculator.toSuffixList(calculator.toList(a)));
        System.out.println(calculator.Calculate(calculator.toSuffixList(calculator.toList(a))));

    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值