当前位置:首页>网络学院>程序开发>c#教程>文章内容

支持函数,变量的算术表达式计算

[ 来源:http://www.it55.com | 作者: | 时间:2007-12-30 | 收藏 | 推荐 ] 【

     
  12 + sin(sqr(9) + 9) + abs(-90)
  给这么一段字符串给你, 要如何才能正确计算出它的值? (注: 值应为 103 )
  
  算术表达式的计算有几种方法,本文只讨论“后缀表达式(也叫'逆波兰表达式')方法”
  后缀表达式是啥意思呢? 顾名思义,就是操作符在操作数的后面,比如 12+36 转换为后缀表达式后就变成
  12 36 +
  
  注:本文中的后缀表达式是用 List 存储,当然用 Stack 也可以(可能用栈会更好)
  
  后缀表达式可以将复杂的算术表达式变得很简单,它的计算逻辑为
  1.遍历整个后缀表达式
  2.如果后缀表达式当前节点是数字,则跳过,继续往下遍历
  3.如果后缀表达式当前节点是操作符,则将前两个节点取出,用当前操作符作运算
   计算完后,将结果存入当前结点, 并删除前两个操作数节点
  重复上面三个过程,直到节点数为 1 (此节点的数据即为最终数据)
  
  
  我们先来模拟一下 12+36*9 这个表达式的计算
  先转换为后缀表达式 12 36 9 * + (转换方法见后续文章)
  
  1. 遍历表达式直到遇见操作符 * (第4个节点)
  2. 取出前两个操作数(36 和 9) 和 * 作运算,结果存入当前节点
   执行完此步骤后,后缀表达式为
   12 324 +
  3. 再重复1,2两步骤,即可得到最终结果 336 , 是不是很简单呢?
  
  下面我们来构造一个可计算后缀表达式的类
  先定义节点类型枚举
  
  
   /**//// <summary>
   /// 节点类型
   /// </summary>
   public enum TokenType
   {
   /**//// <summary>
   /// 操作数
   /// </summary>
   Numeric,
   /**//// <summary>
   /// 操作符
   /// </summary>
   Operator
   }
  操作符枚举
  
  
   public enum OperatorType
   {
   Plus, //"+",
   Subtract,// "-",
   MultiPly,// "*",
   Divide, //"/",
   //后面可继续添加函数等
   }
  
  节点类
  
  
   /**//// <summary>
   /// 节点类
   /// </summary>
   public class ExpressionToken
   {
   private TokenType type;
  
   /**//// <summary>
   /// 节点类型
   /// </summary>
   public TokenType Type
   {
   get { return type; }
   set { type = value; }
   }
   private object data;
  
   /**//// <summary>
   /// 节点数据
   /// </summary>
   public object Data
   {
   get { return data; }
   set { data = value; }
   }
  
   /**//// <summary>
   /// 构造函数
   /// </summary>
   /// <param name="type">节点类型</param>
   /// <param name="data">节点数据</param>
   public ExpressionToken(TokenType type, object data)
   {
   this.type = type;
   this.data = data;
   }
   }
  表达式计算类
  
  
   public class Expression
   {
   /**//// <summary>
   /// 表达式节点列表
   /// </summary>
   List<ExpressionToken> lstExp = new List<ExpressionToken>();
  
   string strExpression;
   public Expression(string exp)
   {
   if (exp == null)
   throw new ArgumentNullException();
   strExpression = exp;
   }
  
   /**//// <summary>
   /// 开始计算
   /// </summary>
   /// <returns></returns>
   private object CalcInner(List<ExpressionToken> exp)
   {
   int index = 0;
   //储存数据
   List<decimal?> digit = new List<decimal?>();
   while (index < exp.Count)
   {
   if (exp.Count == 1 && exp[0].Type == TokenType.Numeric)

(编辑:IT资讯之家 www.it55.com

返回顶部
共2页: 上一页 1 [2] 下一页  

网友评论

[以下评论为网友观点,不代表本站。请自觉遵守互联网相关政策法规,所有连带责任均有评论者自负。]
[不超过250字]