java实现计算器,能够进行负数运算

import java.util.*;
import java.util.Stack;
public class Three {
    public static void main(String[] args){
        Double result = Calculate.result("(3+1)+1/3+9");
        System.out.println(result);
    }
}

class Calculate {
    //计算结果
    public static Double result(String str) {
        List<String> strList = strToStrList(str);
        List<String> postList = toPostOrder(strList);
        Double result = getResult(postList);
        return result;
    }
    //将字符串转换为字符串List
    private static List<String> strToStrList(String str) {
        List<String> strList = new ArrayList<>();
        int begin=0,end=0,post=0,i=0;
        for (; i < str.length(); i++) {
            if (str.charAt(i) == '+' || str.charAt(i) == '-' || str.charAt(i) == '*'
                || str.charAt(i) == '/' || str.charAt(i) == '(' || str.charAt(i) == ')') {
                end = i;
                if (begin < end) {
                    strList.add(str.substring(begin, end));
                    strList.add(str.substring(i,i+1));
                }
                //连续符号时
                else {
                    strList.add(str.substring(i,i+1));
                }
                begin = i + 1;
            }
        }
        //如果没有if包裹,当最后一个字符为操作符时,List末尾会添加一个空字符串
        if (!"".equals(str.substring(begin, str.length()))){
            strList.add(str.substring(begin, str.length()));
        }
        return strList;
    }
    /*
    将中缀表达式转换为后缀表达式
     */
    private static List<String> toPostOrder(List<String> strList) {
        /*规则:
 53         *1,运算数直接输出
 54         *2,左括号压入堆栈
 55         *3,右括号 将栈顶的运算符弹出并输出,括号出栈不输出
 56         *4,运算符:
 57         *    若优先级大于栈顶运算符,压入栈
 58         *    若优先级小于或等于栈顶运算符,栈顶运算符弹出并输出,
 59         *       继续和新栈顶比较,直到比栈顶运算符优先级大,将它压入栈
 60         *5,对象处理完毕后,将栈中运算符弹出并输出
 61         */
        Stack<String> operStack = new Stack<>();
        List<String> postList = new ArrayList<>();
        for (int i = 0; i < strList.size(); i++) {
            if (isOper(strList.get(i), i, strList)) {
                //堆栈为空时操作符直接入栈
                if (operStack.isEmpty()) {
                    operStack.push(strList.get(i));
                } else {
                    //操作符为"("时直接入栈
                    if ("(".equals(strList.get(i))) {
                        operStack.push(strList.get(i));
                    } else if (")".equals(strList.get(i))) {
                        //操作符为")"时栈顶出栈并输出,直到遇到"(", "("出栈,")"不入栈
                        while (!"(".equals(operStack.peek())) {
                            postList.add(operStack.pop());
                        }
                        operStack.pop();
                    } else {
                        //其他操作符需要比较与栈顶元素的优先级
                        if ("(".equals(operStack.peek())) {
                            operStack.push(strList.get(i));
                        } else {
                            //优先级高,直接入栈
                            if (!operStack.isEmpty() && getPriority(strList.get(i)) > getPriority(operStack.peek())) {
                                operStack.push(strList.get(i));
                            } else {
                                if (!operStack.isEmpty() && getPriority(strList.get(i)) <= getPriority(operStack.peek()) && !"(".equals(operStack.peek())){

                                }
                                //优先级低或者相等,栈顶元素出栈,直到优先级比栈顶元素高
                                while (!operStack.isEmpty() && getPriority(strList.get(i)) <= getPriority(operStack.peek()) && !"(".equals(operStack.peek())) {
                                    postList.add(operStack.pop());
                                }

                                if (operStack.isEmpty()) {
                                    //若堆栈元素全部被弹出,直接入栈
                                    operStack.push(strList.get(i));
                                } else if (getPriority(strList.get(i)) > getPriority(operStack.peek()) || "(".equals(operStack.peek())) {
                                    //若优先级高,入栈
                                    operStack.push(strList.get(i));
                                }
                            }
                        }
                    }
                }
            } else {
                //操作数直接添加
                if ("-".equals(strList.get(i))){

                }else if (i >= 2 && "-".equals(strList.get(i - 1)) && "(".equals(strList.get(i - 2)) ) {
                    postList.add(strList.get(i - 1) + strList.get(i));
                } else if (i == 1 && "-".equals(strList.get(i - 1))) {
                    postList.add(strList.get(i - 1) + strList.get(i));
                } else {
                    postList.add(strList.get(i));
                }
            }
        }
        //最后将所有元素出栈
        while (!operStack.isEmpty()) {
            postList.add(operStack.pop());
        }
        return postList;
    }
    /**
     * 计算后缀表达式
     */
    private static double getResult(List<String> postList) {
        /*规则:
157         *中缀表达式不用比较优先级
158         *将运算数入栈,每读到一个运算符
159         *就弹出栈顶的两个运算数,运算完毕后将结果压入栈
160         */
        Stack<String> numStack = new Stack();
        for(int i =0 ; i < postList.size(); i++) {
            if (isNum(postList.get(i))) {
                numStack.push(postList.get(i));
            } else if (isOper(postList.get(i), i, postList)) {

                if ("+".equals(postList.get(i))) {
                    Double num2 = Double.parseDouble(numStack.pop());
                    Double num1 = Double.parseDouble(numStack.pop());
                    Double result = num1 + num2;
                    numStack.push(result.toString());
                } else if ("-".equals(postList.get(i))) {
                    Double num2 = Double.parseDouble(numStack.pop());
                    Double num1;
                    //能计算负数开头
                    if (numStack.isEmpty()) {
                        num1 = 0.0;
                    } else {
                        num1 = Double.parseDouble(numStack.pop());
                    }
                    Double result = num1 - num2;
                    numStack.push(result.toString());
                } else if ("*".equals(postList.get(i))) {
                    Double num2 = Double.parseDouble(numStack.pop());
                    Double num1 = Double.parseDouble(numStack.pop());
                    Double result = num1 * num2;
                    numStack.push(result.toString());
                } else if ("/".equals(postList.get(i))) {
                    Double num2 = Double.parseDouble(numStack.pop());
                    Double num1 = Double.parseDouble(numStack.pop());
                    Double result = num1 / num2;
                    numStack.push(result.toString());
                }
            }
        }
        return Double.parseDouble(numStack.pop());
    }
    /*
   判断该字符串是否为操作符
   */
    private static boolean isOper(String str, int i, List<String> stringList){
        if("*".equals(str)|| "/".equals(str)||
                "+".equals(str)||
                "(".equals(str)|| ")".equals(str)){
            return true;
        } else if ("-".equals(str)) {
            return !(i>=1 && "(".equals(stringList.get(i-1)));
        }
        else{
            return false;
        }
    }
    /*
    判断该字符串是否为操作数
    */
    private static boolean isNum(String str){
        if("*".equals(str)|| "/".equals(str)||
                "+".equals(str)|| "-".equals(str)||
                "(".equals(str)|| ")".equals(str)){
            return false;
        }
        else{
            return true;
        }
    }
    /*
    得到操作符的优先级
    */
    private static int getPriority(String c){
        if("*".equals(c) || "/".equals(c)){
            return 2;
        } else if ("+".equals(c) || "-".equals(c)){
            return 1;
        } else {
            return 999;
        }
    }
}
  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

我橘子超酸

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

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

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

打赏作者

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

抵扣说明:

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

余额充值