• 公式编辑器


      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);
            }
        }
    
  • 相关阅读:
    HTML清除浮动的几种形式
    HTML和XML的区别
    CSS选择器的优先级
    CSS选择器
    PHP单文件和多文件的上传(示例)
    单元测试
    定义person类及其子类,并按要求设计、定义和实例化类 (实例)
    CSS的 行内元素 和 块类元素
    小心了!Kubernetes自动化操作工具将让你失去工作
    开源云计算厂商:浅析渠道激活平台的打造
  • 原文地址:https://www.cnblogs.com/Fuss/p/3352577.html
Copyright © 2020-2023  润新知