关于中缀表达式和逆波兰表达式(终结篇)中

我在上一篇中简单概述了逆波兰表达式的用途,中缀表达式转换逆波兰表达式的标准算法,还有逆波兰表达式的计算方法。这一篇,我将给出中缀表达式转换逆波兰表达式时各运算符的运算级别。

 

运算符的运算级别即方程式运算的先后级别,如下:

 

运算符

级别

空格

0

)

1

(

2

+,-

3

*,/

4

运算对象

-1

 

我现在给出中缀表达式转换逆波兰表达式的C#源代码,该代码在.net2005运行通过。由于时间原因部分代码未作优化,希望有兴趣的朋友能请给我提出更好的建议。

 

[Serializable]

        /// <summary>

        /// 操作符结构

        /// </summary>

        private struct Operator

        {

            public string OperatorStack;

            public int Level;

            public Operator(string OperatorStack, int Level)

            {

                this.OperatorStack = OperatorStack;

                this.Level = Level;

 

            }

        }

        /// <summary>

        /// 操作符运算级别

        /// </summary>

        /// <param name="strOperator">操作符</param>

        /// <returns>操作运算符,空格返回0,出错返回-1</returns>

        private int OperatorLevel(string strOperator)

        {

            switch (strOperator)

            {

                case "+":

                    return 3;

                case "-":

                    goto case "+";

                case "*":

                    return 4;

                case "/":

                    goto case "*";

                case "(":

                    return 2;

                case ")":

                    return 1;

                case " ":

                    return 0;

                default:

                    return -1;

 

            }

        }

        /// <summary>

        /// 将中缀表达式转换为逆波兰表达式

        /// </summary>

        /// <param name="Expression">标准中缀表达式</param>

        /// <returns>标准逆波兰表达式</returns>

        public string RpnExpression(string Expression)

        {

            try

            {

                //加入结束标记

                string strExpression = Expression + "#";

 

                //定义出栈和入栈堆栈

               

                string[] strNum = Expression.Split(new char[] { '+', '-', '*', '/', '(', ')' });

                int intNum = strNum.GetLength(0);

                //操作运算符堆栈

                Stack oper = new Stack();

                //定义输出堆栈

                Stack output = new Stack();

 

                //定义前缀表达式字符读取指针

                int i = 0;

               

                //定义当前读取数字数组指针

                int n = 0;

                //定义操作运算符级别函数

                Operator op=new Operator();

                //输出堆栈的大小

                int intStackCount=0;

 

                //从左到右读取前缀表达式

                while (i < strExpression.Length)

                {

                    //读取一个字符

                    string strChar = strExpression.Substring(i, 1);

                    if (strChar != "#")

                    {

                        //取字符的运算级别

                        int intLevel = this.OperatorLevel(strChar);

                        if (intLevel == 0)

                        //遇空格读取下一字符

                        {

                            i++;

                        }

                        else if (intLevel == -1)

                        //数字直接推入输出堆栈

                        {

                            for (int m = n; m < strNum.GetLength(0); m++)

                            {

                                if (strNum[m] != "")

                                {

                                    //移动数组指针

                                    n = m + 1;

                                    //将数字直接推入堆栈

                                    output.Push(strNum[m]);

                                    //移动字符串读取指针

                                    i = i + strNum[m].Length;

                                    break;

                                }

                            }

                        }

                        else //操作字符根据运算字符级别推入运算符堆栈

                        {

                            if (oper.Count == 0)

                            {

                                //运算符堆栈为空,直接推入堆栈

                                oper.Push(new Operator(strChar, intLevel));

                                //移动字符读取指针

                                i++;

                            }

                            else

                            {

                                op = (Operator)oper.Peek();

                                if (intLevel > op.Level || intLevel == 2)

                                {

                                    //运算字符比运算符堆栈最后的级别高或者运算符为'('直接推入运算符堆栈

                                    oper.Push(new Operator(strChar, intLevel));

                                    //移动字符读取指针

                                    i++;

                                }

                                else

                                {

                                    //运算字符不高于运算符堆栈最后的级别,则将运算符堆栈出栈,直到比其高为止

                                    intStackCount = oper.Count;

                                    for (int m = 0; m < intStackCount; m++)

                                    {

                                        op = (Operator)oper.Peek();

                                        if (op.Level >= intLevel)

                                        {

                                            //将操作符出栈并压入输入堆栈

                                            output.Push(op.OperatorStack);

                                            int l = op.Level;

                                            oper.Pop();

                                            if (l == 2)

                                            {

                                                //如果操作符堆栈中最后的操作符为'('则停止出栈

                                                i++;

                                                break;

                                            }

 

 

 

                                        }

                                        else

                                        {

                                            //直到运算符已经高出运算符栈中最后的级别,则入栈

                                            oper.Push(new Operator(strChar, intLevel));

                                            i++;

                                            break;

                                        }

                                    }

                                }

                            }

                        }

                    }

                    else

                    {

                        //读取前缀表达式结尾将运算符堆栈直接压入输出堆栈

                        intStackCount = oper.Count;

                        for(int m=0;m<intStackCount;m++)

                        {

                            op = (Operator)oper.Peek();

                            output.Push(op.OperatorStack);

                            oper.Pop();

                         }

                        i++;

                    }

                }

                //形成逆波兰表达式输出字符串

                object[] strOutput = output.ToArray();

                string str = Convert.ToString(strOutput[strOutput.GetLength(0) - 1]);

                for (int m = strOutput.GetLength(0)-2; m >= 0;m-- )

                {

                    if (Convert.ToString(strOutput[m]) != "(" && Convert.ToString(strOutput[m]) != ")")

                    {

                        str = str + "," + Convert.ToString(strOutput[m]);

                    }

                }

                return str;

            }

            catch (Exception ex)

            {

                MessageBox.Show(ex.Message.ToString());

                return "";

            }

        }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值