如何使用C#中的堆栈计算Infix-Expression的输出

时间:2017-05-25 19:41:46

标签: c# methods stack infix-notation

我已经在Stackoverflow上找到了不同的解决方案,但有一些我不理解的东西。

计算输出的最佳方法是什么:((1 +(4 *(2 + 3)))+((2 + 3)*(4 * 5)))?

我的方法如下,但我知道它有很多错误:

public static int ComputeInfix(string infix) {
        Stack<char> operatorstack = new Stack<char>();
        Stack<int> operandstack = new Stack<int>();
        for(int j = 0; j < infix.Length; j++) {
            char c = infix[j];
            if (c => 0 && c <= 9) {
                operandstack.Push(c);
            }
            else if ((c == '+' || c == '*' ||  c == '/' || c == '-')) {
                if (operatorstack.IsEmpty()) {
                    operatorstack.Push(c);
                }
                else {
                    if (operatorstack.Peek() != '*' || operatorstack.Peek() != '/') {
                        operatorstack.Push(c);
                    }
                }
            } 
            else if (c == '(') {
                operatorstack.Push(c);
            }
            else if (c == ')') {
                operatorstack.Pop();
            }
        }
        return infix;
    }

现在改为:

Stack<char> operatorstack = new Stack<char>();
        Stack<char> operandstack = new Stack<char>();
        for(int j = 0; j < infix.Length; j++) {
            char c = infix[j];
            if (c => '0' && c <= '9') {
                operandstack.Push(c);
            }

但是得到错误:

  

Infix.cs(16,8):错误CS0136:名为c' cannot be declared in this scope because it would give a different meaning to c'的局部变量,已在“父或当前”范围内用于表示   别的什么

1 个答案:

答案 0 :(得分:0)

由于我花时间写它,这是我的解决方案:

public static int ComputeInfix(string infix) {
    var operatorstack = new Stack<char>();
    var operandstack = new Stack<int>();

    var precedence = new Dictionary<char, int> { { '(', 0 }, { '*', 1 }, { '/', 1 }, { '+', 2 }, { '-', 2 }, { ')', 3 } };

    foreach (var ch in $"({infix})") {
        switch (ch) {
            case var digit when Char.IsDigit(digit):
                operandstack.Push(Convert.ToInt32(digit.ToString()));
                break;
            case var op when precedence.ContainsKey(op):
                var keepLooping = true;
                while (keepLooping && operatorstack.Count > 0 && precedence[ch] > precedence[operatorstack.Peek()]) {
                    switch (operatorstack.Peek()) {
                        case '+':
                            operandstack.Push(operandstack.Pop() + operandstack.Pop());
                            break;
                        case '-':
                            operandstack.Push(-operandstack.Pop() + operandstack.Pop());
                            break;
                        case '*':
                            operandstack.Push(operandstack.Pop() * operandstack.Pop());
                            break;
                        case '/':
                            var divisor = operandstack.Pop();
                            operandstack.Push(operandstack.Pop() / divisor);
                            break;
                        case '(':
                            keepLooping = false;
                            break;
                    }
                    if (keepLooping)
                        operatorstack.Pop();
                }
                if (ch == ')')
                    operatorstack.Pop();
                else
                    operatorstack.Push(ch);
                break;
            default:
                throw new ArgumentException();
        }
    }

    if (operatorstack.Count > 0 || operandstack.Count > 1)
        throw new ArgumentException();

    return operandstack.Pop();
}