公式编辑器

  ERP系统业务繁杂,为应对变化,通常会用到公式编辑器。联想到大学学过的汇编原理,国庆期间一个人没事干,就略微温习了下,花了几个小时写了个公式编辑器。面向对象搞多了,算法能力和记忆力都慢慢弱化了,呜呼哀哉!

  本公式编辑器实现的功能很简单,就是计算加减乘除。未进行公式的校验,也未涉及逻辑运算,目的只是单纯地温习下大学的理论基础,同时希望能给其他人一些启发。采用逆波兰式算法,运行结果如下所示。下载源代码

公式编辑器

 

  实现代码如下:

    public class CalculateHelper

    {

        //定义算术运算符的优先级

        private int GetOperatorPriorityLevel(char oper)

        {

            switch (oper)

            {

                case '#':

                    return 0;

                case '+':

                    return 1;

                case '-':

                    return 1;

                case '*':

                    return 2;

                case '/':

                    return 2;

                default:

                    return -1;

            }

        }



        //oper1优先级高于oper2,返回正数,反之返回负数,相等则返回0

        private int ComparePriority(char oper1, char oper2)

        {

            return GetOperatorPriorityLevel(oper1) - GetOperatorPriorityLevel(oper2);

        }



        //中缀表达式转后缀表达式

        public Queue<string> MiddleToSuffix(string expression)

        {

            Stack<char> temporaryStack = new Stack<char>();

            temporaryStack.Push('#');

            Queue<string> suffixExpression = new Queue<string>();

            string temNum = "";

            for (int i = 0; i < expression.Length; i++)

            {

                if (expression[i] == ' ')//过滤空格

                    continue;

                #region 处理数字

                if (char.IsNumber(expression[i]) || expression[i] == '.')

                {

                    temNum += expression[i];

                    if ((i == expression.Length - 1))//字符串已经处理结束

                        suffixExpression.Enqueue(temNum);

                    continue;

                }

                else

                {

                    if (temNum != "")

                        suffixExpression.Enqueue(temNum);

                    temNum = "";

                }

                #endregion

                #region 处理括号

                if (expression[i] == '(')

                    temporaryStack.Push(expression[i]);

                else if (expression[i] == ')')

                {

                    while (temporaryStack.Peek() != '#') //退栈并输出,直至遇到  '('

                    {

                        char top = temporaryStack.Pop();

                        if (top == '(')

                            break;

                        suffixExpression.Enqueue(top.ToString());

                    }

                }

                #endregion

                #region 处理运算符

                else // 是运算符,比较优先级

                {

                    char top = temporaryStack.Peek();

                    while (ComparePriority(expression[i], top) <= 0)//保证栈顶元素优先级最高

                    {

                        suffixExpression.Enqueue(top.ToString());

                        temporaryStack.Pop();

                        top = temporaryStack.Peek();

                    }

                    if (expression[i] != ')') //右括号不入栈

                        temporaryStack.Push(expression[i]);

                }

                #endregion

            }

            while (temporaryStack.Count > 1)

                suffixExpression.Enqueue(temporaryStack.Pop().ToString());

            return suffixExpression;

        }



        private double Calculate(string operand1, string operand2, string oper)

        {

            double oper1 = double.Parse(operand1);

            double oper2 = double.Parse(operand2);

            switch (oper)

            {

                case "+":

                    return oper1 + oper2;

                case "-":

                    return oper1 - oper2;

                case "*":

                    return oper1 * oper2;

                case "/":

                    return oper1 / oper2;

                default:

                    throw new Exception("操作符有误!");

            }

        }



        //计算中缀表达式的结果

        public double GetResult(string expression)

        {

            Queue<string> suffixExpression = MiddleToSuffix(expression);

            Stack<string> resultStack = new Stack<string>();

            while (suffixExpression.Count() > 0)

            {

                string oper = suffixExpression.Dequeue();

                if (oper == "+" || oper == "-" || oper == "*" || oper == "/")//为操作符,就计算

                {

                    string oper2 = resultStack.Pop();

                    string oper1 = resultStack.Pop();

                    string temresult = Calculate(oper1, oper2, oper).ToString();

                    resultStack.Push(temresult);

                }

                else

                    resultStack.Push(oper);

            }

            string result = resultStack.Pop();

            return double.Parse(result);

        }

    }

 

你可能感兴趣的:(编辑器)