C#中的Shunting Yard算法只在某些时候有效

时间:2016-02-22 22:40:13

标签: c# tree expression postfix-notation

我正在从中缀表达式构建表达式树。目前我正在转换为postfix,然后构建树。我的代码适用于大多数表达式但不是全部。我对括号的实现做错了。这是我的代码 -

readonly static char[] operators = { '+', '-', '*', '/' };

       string order_of_op(string op1, string op2)
       {
            if (op1 == "*" || op1 == "/")//is op1 higher?
            {
                return op1;//it is so return it
            }
            else if ((op2 == "*" || op2 == "/"))//is op2 higher
            {
                return op2;//it is so return it
            }
            else
                return op1;// they are both addition or subtraction so    return op1.
        }


        Queue<string> convert_to_postfix(string infix) //following the    Shunting-yard algorithm
        {
            Queue<string> num_queue = new Queue<string>();
            Stack<string> op_stack = new Stack<string>();
            Stack<string> temp_stack = new Stack<string>();
            string temp = "";

            foreach (char s in infix)
            {
                if (operators.Contains(s) == true)//if its a function push it on the stack
                {
                    if (temp != "")//make sure we don't push an empty string
                        num_queue.Enqueue(temp);
                    if (op_stack.Count != 0)//make sure we dont crash popping from empty stack
                    {
                        if (op_stack.Peek() != "(")//if we dont have a parenthese on top proceed as normal
                        {
                            if (op_stack.Count > 1)
                            {
                                while (op_stack.Count != 0 && order_of_op(op_stack.Peek(), s.ToString()) == op_stack.Peek())
                                {
                                    num_queue.Enqueue(op_stack.Pop());
                                }

                            }
                        }
                        op_stack.Push(s.ToString());
                    }
                    else
                    {
                        op_stack.Push(s.ToString());
                    }

                    temp = "";
                }
                else if (s == '(')
                {
                    op_stack.Push(s.ToString());
                }
                else if (s == ')')
                {
                    if (temp!= "")
                        num_queue.Enqueue(temp);
                    temp = "";
                    while (op_stack.Peek() != "(")
                    {
                        num_queue.Enqueue(op_stack.Pop());
                    }
                    op_stack.Pop();
                    if (op_stack.Count > 1)
                    {
                        if (operators.Contains(op_stack.Peek()[0]) == true)
                        {
                            num_queue.Enqueue(op_stack.Pop());
                        }
                    }
                }
                else
                {
                    temp += s;
                }
            }

            if (temp != "")
            {
                num_queue.Enqueue(temp);
            }

            foreach (string s in op_stack)
            {
                num_queue.Enqueue(s);
            }

            Console.Write("Postfix = ");
            foreach (string s in num_queue)
            {
                Console.Write(s);
            }
            Console.WriteLine();

            return num_queue;
        }

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我修好了!我不得不改变的是 -

if (op_stack.Count > 1)

if (op_stack.Count >= 1)