公式编辑器

http://www.cnblogs.com/Fuss/p/3352577.html

 

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值