算法 计算四则运算字符串结果

RingBuffer面试后面一场,输入一个字符串,计算结果

字符串内容限制为“ 0-9,+,-,*,/”这些符号

例如输入"1+2*3/4-5",返回-2.5。

 

开始到时候直接想到了可以用树来维护计算关系,后来被问可以用其他数据结构么,然后想到应该用栈来实现,写的时候用了一个,写到后面突然意识到应该用两个栈,一个存数据,一个存操作符。

在家里写了完成大概写了一个小时不到,当时是没写完,后来口述了一下逻辑。

重点在于:

1.第一个符号到判断,可能第一个字符是“+”或者“-”。

2.末尾非法符号判断。

3.中间连续连个操作符的判断。

具体是几行粗体代码

 

package com.ljw.javatest;

import java.util.LinkedList;
import java.util.Stack;

public class Calculate {

    public static void print(Object value) {
        System.out.println(value);
    }

    public static void main(String[] args) throws Exception {
        String input = null;

        input = "1+2*3/4-5";
        print(calculate(input) == -2.5);

        input = "-1+2*3/4-5";
        print(calculate(input) == -4.5);

        try {
            input = "";
            calculate(input);
        } catch (Exception ex) {
            print(ex.getMessage().equals(exMsg));
        }

        try {
            input = null;
            calculate(input);
        } catch (Exception ex) {
            print(ex.getMessage().equals(exMsg));
        }

        try {
            input = "1+2*3/4-a5";
            calculate(input);
        } catch (Exception ex) {
            print(ex.getMessage().equals(exMsg));
        }

        try {
            input = "1+2*a3/4-5";
            calculate(input);
        } catch (Exception ex) {
            print(ex.getMessage().equals(exMsg));
        }

        try {
            input = "1+2**3/4-5";
            calculate(input);
        } catch (Exception ex) {
            print(ex.getMessage().equals(exMsg));
        }

        try {
            input = "1+2*3/4+-5";
            calculate(input);
        } catch (Exception ex) {
            print(ex.getMessage().equals(exMsg));
        }

        try {
            input = "1+-2*3/4-5";
            calculate(input);
        } catch (Exception ex) {
            print(ex.getMessage().equals(exMsg));
        }

        
        try {
            input = "1-2*3/4-5-";
            calculate(input);
        } catch (Exception ex) {
            print(ex.getMessage().equals(exMsg));
        }

    }

    static String exMsg = "invalid input";

    public static double calculate(String input) throws Exception {
        if (input == null || input.length() == 0) {
            throw new Exception(exMsg);
        }

        char[] arr = input.toCharArray();
        Stack<Double> valueStack = new Stack();
        Stack<String> opStack = new Stack();

        StringBuilder sb = new StringBuilder();
        boolean flag = false;
        for (int i = 0; i < arr.length; i++) {
            char temp = arr[i];
            if (temp != '+' && temp != '-' && temp != '*' && temp != '/') {
                if (temp < '0' || temp > '9') {
                    throw new Exception(exMsg);
                }
                sb.append(temp);

                continue;
            }
            Double value = null;
            if (sb.length() != 0) {
                value = Double.parseDouble(sb.toString());
                sb.setLength(0);
            }

            if(i<arr.length-1
                &&!(arr[i+1] != '+' && arr[i+1] != '-' && arr[i+1] != '*' && arr[i+1] != '/')){
                throw new Exception(exMsg);
            }
            if(i==arr.length-1){
                throw new Exception(exMsg);
            }

            if (flag) {
                if (value == null) {
                    throw new Exception(exMsg);
                }
                Double a = valueStack.pop();
                String op = opStack.pop();
                switch (op) {
                case "*":
                    value = a * value;
                    break;
                case "/":
                    value = a / value;
                    break;
                // default:
                //     throw new Exception(exMsg);
                }
                valueStack.push(value);
            } else {
                if (value != null) {
                    valueStack.push(value);
                }
            }

            opStack.push(String.valueOf(temp));
            if (temp == '+' || temp == '-') {
                flag = false;
            } else {
                flag = true;
            }
        }
        // if (sb.length() == 0) {
        //     throw new Exception(exMsg);
        // }
        valueStack.push(Double.parseDouble(sb.toString()));

        double result = valueStack.pop();

        while (!valueStack.isEmpty() && !opStack.isEmpty()) {
            double value = valueStack.pop();
            String op = opStack.pop();
            // 第一个输入可能是带符号
            if (valueStack.isEmpty() && opStack.size() == 1) {
                String extra = opStack.pop();
                if (extra.equals("-")) {
                    value = 0 - value;
                }
            }
            switch (op) {
            case "-":
                result = value - result;
                break;
            case "+":
                result = value + result;
                break;
            // default:
            //     throw new Exception(exMsg);
            }

        }

        // if (!valueStack.isEmpty() || !opStack.isEmpty()) {
        //     throw new Exception(exMsg);
        // }

        return result;
    }
}

 

posted on 2019-07-10 23:49  Lv Jianwei  阅读(574)  评论(0编辑  收藏  举报