中缀算法只返回最后一个数字

Infix algorithm returning last number only

我有以下 class 来评估公式,return result.It 使用 infix algorithm 和 2 个不同的堆栈来推送值和运算符。当公式 有空格 分隔字符时,例如: 2 + 3 * 4 它有效,但当它没有空格时,例如: 2+3*4 它不起作用。我需要在没有空格的情况下工作的功能,但我看不到必须在哪里修改代码。

package calculator;

import java.util.Stack; 

public class EvaluateString 
{ 
    public static int evaluate(String expression) 
    { 
            System.out.println(expression);
        char[] tokens = expression.toCharArray(); 
                System.out.println(tokens);
        // Stack for numbers: 'values' 
        Stack<Integer> values = new Stack<Integer>(); 

        // Stack for Operators: 'ops' 
        Stack<Character> ops = new Stack<Character>(); 

        for (int i = 0; i < tokens.length; i++) 
        { 

            // Current token is a number, push it to stack for numbers 
            if (tokens[i] >= '0' && tokens[i] <= '9') 
            { 
                StringBuffer sbuf = new StringBuffer(); 
                // There may be more than one digits in number 
                while (i < tokens.length && tokens[i] >= '0' && tokens[i] <= '9') 
                    sbuf.append(tokens[i++]); 
                values.push(Integer.parseInt(sbuf.toString())); 
            } 


            // Current token is an operator. 
            else if (tokens[i] == '+' || tokens[i] == '-' || 
                    tokens[i] == '*' || tokens[i] == '/') 
            { 
                // While top of 'ops' has same or greater precedence to current 
                // token, which is an operator. Apply operator on top of 'ops' 
                // to top two elements in values stack 
                while (!ops.empty() && hasPrecedence(tokens[i], ops.peek())) 
                values.push(applyOp(ops.pop(), values.pop(), values.pop())); 

                // Push current token to 'ops'. 
                ops.push(tokens[i]); 
            } 
        } 

        // Entire expression has been parsed at this point, apply remaining 
        // ops to remaining values 
        while (!ops.empty()) 
            values.push(applyOp(ops.pop(), values.pop(), values.pop())); 

        // Top of 'values' contains result, return it 
        return values.pop(); 
    } 

    // Returns true if 'op2' has higher or same precedence as 'op1', 
    // otherwise returns false. 
    public static boolean hasPrecedence(char op1, char op2) 
    { 

        if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) 
            return false; 
        else
            return true; 
    } 

    // A utility method to apply an operator 'op' on operands 'a' 
    // and 'b'. Return the result. 
    public static int applyOp(char op, int b, int a) 
    { 
        switch (op) 
        { 
        case '+': 
            return a + b; 
        case '-': 
            return a - b; 
        case '*': 
            return a * b; 
        case '/': 
            if (b == 0) 
                throw new
                UnsupportedOperationException("Cannot divide by zero"); 
            return a / b; 
        } 
        return 0; 
    } 

    // Driver method to test above methods 
    public static void main(String[] args) 
    { 
        System.out.println(EvaluateString.evaluate("100*2+12")); 
    } 
}

当你读一个数字时,你会吃掉后面的运算符。您需要递减 i:

        if (tokens[i] >= '0' && tokens[i] <= '9') 
        { 
            StringBuffer sbuf = new StringBuffer(); 
            // There may be more than one digits in number 
            while (i < tokens.length && tokens[i] >= '0' && tokens[i] <= '9') 
                sbuf.append(tokens[i++]); 
            values.push(Integer.parseInt(sbuf.toString())); 
            --i;
        } 

您用于推送操作的第二个 if 语句永远不会执行,因为您实际上通过内部 while 循环跳过了操作 [i++]

 while (i < tokens.length && tokens[i] >= '0' && tokens[i] <= '9') 
                sbuf.append(tokens[i++]); 

但是当你用 空格分隔字符时 例如:2 + 3 * 4 它可以工作,因为你还没有跳过 [i++]

的操作

您可以在指定要推送到您的 values 堆栈的数字后简单地 decrease the counter

if (tokens[i] >= '0' && tokens[i] <= '9') 
        { 
            StringBuffer sbuf = new StringBuffer(); 
            // There may be more than one digits in number 
            while (i < tokens.length && tokens[i] >= '0' && tokens[i] <= '9') 
                sbuf.append(tokens[i++]); 
            values.push(Integer.parseInt(sbuf.toString())); 
            --i;
        }