如何在 C# 中使用堆栈计算中缀表达式的输出 [英] How to calculate output of Infix-Expression by using stacks in C#

查看:33
本文介绍了如何在 C# 中使用堆栈计算中缀表达式的输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在 Stackoverflow 上找到了不同的解决方案,但有些东西我不明白.

I already found different solutions on Stackoverflow, but there were some things I didn´t understand.

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

Whats the best method to calculate the Output of e.g.: ((1+(4*(2+3)))+((2+3)*(4*5))) ?

我的方法如下所示,但我知道其中有很多错误:

My method looks as following, but I know there are lots of mistakes in it:

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): error CS0136: A local variable named c' cannot be在此范围内声明,因为它会给c',已在父级或当前"范围中使用,以表示别的东西

Infix.cs(16,8): error CS0136: A local variable named c' cannot be declared in this scope because it would give a different meaning to c', which is already used in a `parent or current' scope to denote something else

推荐答案

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

Since I spent the time to write it, here is my solution:

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();
}

这篇关于如何在 C# 中使用堆栈计算中缀表达式的输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆