使用括号的堆栈计算器

时间:2014-02-25 20:00:11

标签: java stack calculator

我正在为一个项目在java中构建一个堆栈,到目前为止,我已经进行了简单的计算,但我希望添加括号以允许更复杂的计算。下面是目前的代码。请记住,我还没有为堆栈内部的运算符设置优先级,而且代码还不是原始代码。你能给予的任何帮助都会很棒。

import java.util.*;

public class CalcEngine {
String total = "";
int op1, op2, size, value1, value2;
char operator;
int displayValue, operand1;
boolean done = false;
Deque<Character> stack = new ArrayDeque<Character>();
ArrayList<Integer> numbers = new ArrayList<Integer>();

/**
 * Create a CalcEngine instance. Initialise its state so that it is ready
 * for use.
 */
public CalcEngine() {
    operator = ' ';
    displayValue = 0;
    operand1 = 0;
}

/**
 * Return the value that should currently be displayed on the calculator
 * display.
 */
public String getDisplayValue() {
    return (total);
}

/**
 * A number button was pressed. Do whatever you have to do to handle it. The
 * number value of the button is given as a parameter.
 */
public void numberPressed(int number) {
    displayValue = displayValue * 10 + number;
    total += number;
}

/**
 * The 'plus' button was pressed.
 */
public void plus() {
    operand1 = displayValue;
    displayValue = 0;
    operator = '+';
    total += " + ";
}

/**
 * The 'minus' button was pressed.
 */
public void minus() {
    operand1 = displayValue;
    displayValue = 0;
    operator = '-';
    total += " - ";
}

public void multiply() {
    operand1 = displayValue;
    displayValue = 0;
    operator = '*';
    total += " * ";
}

public void divide() {
    operand1 = displayValue;
    displayValue = 0;
    operator = '/';
    total += " / ";
}

/**
 * The '=' button was pressed.
 */
public void equals() {

    stack();
}

/**
 * The 'C' (clear) button was pressed.
 */
public void clear() {
    displayValue = 0;
    operand1 = 0;
    total = "";
}

/**
 * Return the title of this calculation engine.
 */
public String getTitle() {
    return ("My Calculator");
}

/**
 * Return the author of this engine. This string is displayed as it is, so
 * it should say something like "Written by H. Simpson".
 */
public String getAuthor() {
    return ("T.Tubbritt");
}

/**
 * Return the version number of this engine. This string is displayed as it
 * is, so it should say something like "Version 1.1".
 */
public String getVersion() {
    return ("Ver. 1.0");
}

public boolean isNumber(String total) {
    try {
        int y = Integer.parseInt(total);
        return true;
    } catch (NumberFormatException e) {
        return false;
    }

}

public void stack() {
    String outputStream;

    StringTokenizer st = new StringTokenizer(total);

    while (st.hasMoreTokens()) {
        String c = st.nextToken();

        if (isNumber(c)) {
            numbers.add(Integer.parseInt(c));
        } else {
            stack.addFirst(c.charAt(0));
        }

    }

    System.out.println(stack.getFirst());

    while (stack.size() != 0) {

        switch (stack.getFirst()) {
        case '*':
            size = numbers.size();
            value1 = numbers.get(size - 1);
            value2 = numbers.get(size - 2);

            numbers.set(size - 2, value1 * value2);
            stack.pop();
            numbers.remove(size - 1);
            continue;

        case '+':
            size = numbers.size();
            value1 = numbers.get(size - 1);
            value2 = numbers.get(size - 2);
            numbers.set(size - 2, value1 + value2);
            stack.pop();
            numbers.remove(size - 1);
            continue;

        case '-':
            size = numbers.size();
            value1 = numbers.get(size - 1);
            value2 = numbers.get(size - 2);
            numbers.set(size - 2, value2 - value1);
            stack.pop();
            numbers.remove(size - 1);
            continue;
        }

    }
    total += " = " + numbers.get(size - 2);
}
}

2 个答案:

答案 0 :(得分:0)

您的筹码目前适用于整数。我相信你需要让它更通用。它将由操作数和操作符组成。操作数将具有eval方法或其他可返回评估结果的方法。对于像5这样的简单操作数,它将返回值5。对于像(3 3 +)这样的复杂操作数,它将返回评估结果,即6。鉴于此信息:

(3 3 +)5 *

将被解析为:

Operand<3 3 +> Operand<5> Operator<*>

将进一步解析为

Operand<Operand<3> Operand<3> Operator<+>> Operand<5> Operator<*>

答案 1 :(得分:0)

如果你想要你可以使用我的代码,我已经实现了它而不使用堆栈或队列...我已经使用递归来解决它...检查下面的代码:

public class Calculator {

    public static void main(String[] args) {
        String input = "2*((2+4)+(5+4))";
        System.out.println(evaluate(input));
        //System.out.println( Character.digit('2', Character.MAX_RADIX));
    }

    private static double evaluate(String expresion) {
        double result = 0;
        String operation = "";
        List<Character> openBrackets = new ArrayList<Character>();
        List<Character> closeBrackets = new ArrayList<Character>();
        StringBuilder innerInput =new StringBuilder();

        for (int i = 0; i < expresion.length(); i++) {
            char inputChar = expresion.charAt(i);
            if(openBrackets.isEmpty()){
                if (Character.isDigit(inputChar)) {

                    if (operation == "" && result == 0) {
                        result = Character.digit(inputChar, Character.MAX_RADIX);
                        continue;
                    } else if (operation != "") {
                        result = calculateWithOperation(operation, Character.digit(inputChar, Character.MAX_RADIX), result);
                        continue;
                    }
                }
                // if the input is operation then we must set the operation in order
                // to be taken into consideration again ..
                if (inputChar == '+' || inputChar == '-' || inputChar == '*' || inputChar == '/') {
                    operation = Character.toString(inputChar);
                    continue;
                }
            }
            if (inputChar == '(') {
                // set operation to be empty in order to calculate the
                // operations inside the brackets ..
                openBrackets.add(inputChar);
                continue;
            }
            if(inputChar ==')'){
                closeBrackets.add(inputChar);
                if(openBrackets.size() == closeBrackets.size()){
                    openBrackets.remove((Character)'(');
                    closeBrackets.remove((Character)')');
                    double evalResult =  evaluate(innerInput.toString());
                    result = calculateWithOperation(operation,evalResult,result);
                    innerInput.setLength(0);
                }
                if(openBrackets.size()> closeBrackets.size()){
                    continue;
                }
                //break;
            }
            else{
                innerInput.append(inputChar);
            }
        }
        return result;
    }

    /**
     * this method to calculate the simple expressions  
     * @param operation
     * @param inputChar
     * @param output
     * @return
     */
    private static double calculateWithOperation(String operation, double inputChar, double output) {
        switch (operation) {
        case "+":
            output = output + inputChar;
            break;

        case "-":
            output = output - inputChar;
            break;

        case "*":
            output = output * inputChar;
            break;

        case "/":
            output = output / inputChar;
            break;

        default:
            break;
        }
        return output;
    }
}