大一时候写过不科学计算器,那时候碰到好多问题都是头铁莽上去,加特判就完事了,导致屁大点功能写了几百行代码,一点也不优雅(雾)。

今天晚上闲来无事就把那份代码重写了一下,用算数栈的方法,顺便把double改成了大数BigDecimal,妈妈再也不用怕我溢出了~~

具体代码在gitee上 :https://gitee.com/mofanyunxiang/calculator

核心代码不多,都在下面了:

for(int i=0;i<s.length();i++)
        {
            char si=s.charAt(i);
            if(si==')')
            {
                char tc='\0';
                while(!cstack.empty())//将括号内部的东西算完,直到碰到左括号后匹配
                {
                    tc=cstack.pop().toString().charAt(0);
                    if(tc=='(')break;
                    BigDecimal n2=nstack.pop();
                    BigDecimal n1=nstack.pop();
                    n1=add(n1,n2,tc);
                    if(n1==null)return "null";
                    nstack.push(n1);
                }
                if(tc!='(')return "Bracket mismatch";
                //括号不匹配,如果缺右括号的话,默认自动在算式尾部添加,缺左括号则报错
                continue;
            }
            ndj=dj;
            dj=zh(si);
            if(dj==-1||((ndj!=-1&&si=='-')))//数字为-1,或者带负号的数字,负号和减号判断规则见上
            {
                int be=i++;
                while(i<s.length()&&zh(s.charAt(i))<0)i++;
                BigDecimal n1=new BigDecimal(s.substring(be,i));
                i--;
                nstack.push(n1);
                continue;
            }
            if(dj==0)//左括号
            {
                cstack.push(si);
                continue;
            }
            if(dj>=1)//算符计算
            {
                if(cstack.empty())
                {
                    cstack.push(si);
                    continue;
                }
                char tc=cstack.peek().toString().charAt(0);
                while(zh(tc)>=dj)//入栈时如果本算符优先级小于等于栈顶算符,则先计算栈顶算符
                {
                    BigDecimal n2=nstack.pop();
                    BigDecimal n1=nstack.pop();
                    cstack.pop();
                    n1=add(n1,n2,tc);
                    if(n1==null)return "null";
                    nstack.push(n1);
                    if(!cstack.empty())tc=cstack.peek().toString().charAt(0);
                    else tc='0';
                }
                cstack.push(si);//算符入栈
            }

        }
        /**
         * 算式栈全部计算,此时优先级就是出栈顺序,直接计算即可。
         */
        while(!cstack.empty())
        {
            char tc=cstack.pop().toString().charAt(0);
            if(tc=='(')continue;
            BigDecimal n2=nstack.pop();
            BigDecimal n1=nstack.pop();
            n1=add(n1,n2,tc);
            if(n1==null)return "null";
            nstack.push(n1);
        }
        s=nstack.pop().toString();