.Net下的算术表达式解析器的实现思路与源码

.NET 表达式目录树 Expression /通过下面方法得到x.Id.ToString().IndexOf(“5”) ,MethodCallExpression继承于Expression。//得到x => x.Id.ToString().IndexOf(“5”) >= 0,后面的一个参数指的是x,如果有多个则指定多个。//通过lambdaResult.Compile()得到Func这样的委托,然后Invoke是调用委托。//得到IndexOf的方法,然后new Type[]这个代表是得到参数为string的一个方法。 阅读详情

   作为程序设计人员经常会遇到这样的情况,需要将某个指定的字符串表达式转换为算术表达式并计算其结果.使用Delphi的朋友可以在网上获取第三方控件来实现,而.Net框架类库并没有相关的处理类,正好在前不久的给一所大学开发的Web应用中也需要实现相关的处理.就抽空写了一个相关的处理类(实现了大部分的算术运算操作,需要其他运算可以在现有基础上扩展),现将部分代码贴出共大家参考,希望能够在交流中进步、互助中学习、探讨中深入:

//EnumExpress

using System;

namespace ExpressionTest
{
 /// <summary>
 /// EnumExpress 的摘要说明。
 /// </summary>
 public enum EnumExpress
 {
  Add,//加号
  Dec,//减号
  Mul,//乘号
  Div,//除号
  Sin,//正玄
  Cos,//余玄
  Tan,//正切
  ATan,//余切
  Sqrt,//平方根
  Pow,//求幂
  None,//无
 }
}

//ExpressDeal

using System;

namespace ExpressionTest
{
 /// <summary>
 /// ExpressDeal 的摘要说明。
 /// </summary>
 public class ExpressDeal
 {
  static ExpressDeal()
  {
   
  }
  private double CalculateExpress(string strExpression)
  {
   
   string strTemp="";
   string strTempB="";
   string strOne="";
   string strTwo="";
   double ReplaceValue=0;
   while (strExpression.IndexOf("+")!=-1 || strExpression.IndexOf("-")!=-1
    || strExpression.IndexOf("*")!=-1 || strExpression.IndexOf("/")!=-1)
   {
    if (strExpression.IndexOf("*")!=-1)
    {
     strTemp=strExpression.Substring(strExpression.IndexOf("*")+1,strExpression.Length-strExpression.IndexOf("*")-1);
     strTempB=strExpression.Substring(0,strExpression.IndexOf("*"));

     strOne=strTempB.Substring(GetPrivorPos(strTempB)+1,strTempB.Length-GetPrivorPos(strTempB)-1);
     
     strTwo=strTemp.Substring(0,GetNextPos(strTemp));

     ReplaceValue=Convert.ToDouble(GetExpType(strOne))*Convert.ToDouble(GetExpType(strTwo));

     strExpression=strExpression.Replace(strOne+"*"+strTwo,ReplaceValue.ToString());
    }
    else if (strExpression.IndexOf("/")!=-1)
    {
     strTemp=strExpression.Substring(strExpression.IndexOf("/")+1,strExpression.Length-strExpression.IndexOf("/")-1);
     strTempB=strExpression.Substring(0,strExpression.IndexOf("/"));

     strOne=strTempB.Substring(GetPrivorPos(strTempB)+1,strTempB.Length-GetPrivorPos(strTempB)-1);
     
     
     strTwo=strTemp.Substring(0,GetNextPos(strTemp));


     ReplaceValue=Convert.ToDouble(GetExpType(strOne))/Convert.ToDouble(GetExpType(strTwo));

     strExpression=strExpression.Replace(strOne+"/"+strTwo,ReplaceValue.ToString());
    }
    else if (strExpression.IndexOf("+")!=-1)
    {
     strTemp=strExpression.Substring(strExpression.IndexOf("+")+1,strExpression.Length-strExpression.IndexOf("+")-1);
     strTempB=strExpression.Substring(0,strExpression.IndexOf("+"));

     strOne=strTempB.Substring(GetPrivorPos(strTempB)+1,strTempB.Length-GetPrivorPos(strTempB)-1);
     
     strTwo=strTemp.Substring(0,GetNextPos(strTemp));

     ReplaceValue=Convert.ToDouble(GetExpType(strOne))+Convert.ToDouble(GetExpType(strTwo));

     strExpression=strExpression.Replace(strOne+"+"+strTwo,ReplaceValue.ToString());
    }
    else if (strExpression.IndexOf("-")!=-1)
    {
     strTemp=strExpression.Substring(strExpression.IndexOf("-")+1,strExpression.Length-strExpression.IndexOf("-")-1);
     strTempB=strExpression.Substring(0,strExpression.IndexOf("-"));

     strOne=strTempB.Substring(GetPrivorPos(strTempB)+1,strTempB.Length-GetPrivorPos(strTempB)-1);
     
     
     strTwo=strTemp.Substring(0,GetNextPos(strTemp));

     ReplaceValue=Convert.ToDouble(GetExpType(strOne))-Convert.ToDouble(GetExpType(strTwo));

     strExpression=strExpression.Replace(strOne+"-"+strTwo,ReplaceValue.ToString());
    }
   }
   
   return Convert.ToDouble(strExpression);
  }
  
  private double CalculateExExpress(string strExpression,EnumExpress ExpressType)
  {
   double retValue=0;
   switch(ExpressType)
   {
    case EnumExpress.Sin:
     retValue=Math.Sin(Convert.ToDouble(strExpression));
     break;
    case EnumExpress.Cos:
     retValue= Math.Cos(Convert.ToDouble(strExpression));
     break;
    case EnumExpress.Tan:
     retValue= Math.Tan(Convert.ToDouble(strExpression));
     break;
    case EnumExpress.ATan:
     retValue= Math.Atan(Convert.ToDouble(strExpression));
     break;
    case EnumExpress.Sqrt:
     retValue= Math.Sqrt(Convert.ToDouble(strExpression));
     break;
    case EnumExpress.Pow:
     retValue= Math.Pow(Convert.ToDouble(strExpression),2);
     break;
   }
   if (retValue==0) return Convert.ToDouble(strExpression);
   return retValue;
  }
  private int GetNextPos(string strExpression)
  {
   int[] ExpPos=new int[4];
   ExpPos[0]=strExpression.IndexOf("+");
   ExpPos[1]=strExpression.IndexOf("-");
   ExpPos[2]=strExpression.IndexOf("*");
   ExpPos[3]=strExpression.IndexOf("/");
   int tmpMin=strExpression.Length;
   for (int count=1;count<=ExpPos.Length;count++)
   {
    if (tmpMin>ExpPos[count-1] && ExpPos[count-1]!=-1)
    {
     tmpMin=ExpPos[count-1];
    }
   }

   return tmpMin;
   
  }
  private int GetPrivorPos(string strExpression)
  {
   int[] ExpPos=new int[4];
   ExpPos[0]=strExpression.LastIndexOf("+");
   ExpPos[1]=strExpression.LastIndexOf("-");
   ExpPos[2]=strExpression.LastIndexOf("*");
   ExpPos[3]=strExpression.LastIndexOf("/");
   int tmpMax=-1;
   for (int count=1;count<=ExpPos.Length;count++)
   {
    if (tmpMax<ExpPos[count-1] && ExpPos[count-1]!=-1)
    {
     tmpMax=ExpPos[count-1];
    }
   }

   return tmpMax;
   
  }
  public string SpiltExpression(string strExpression)
  {
   string strTemp="";
   string strExp="";

   while (strExpression.IndexOf("(")!=-1)
   {
    strTemp=strExpression.Substring(strExpression.LastIndexOf("(")+1,strExpression.Length-strExpression.LastIndexOf("(")-1);
    strExp=strTemp.Substring(0,strTemp.IndexOf(")"));
    strExpression=strExpression.Replace("("+strExp+")",CalculateExpress(strExp).ToString());

   }
   if(strExpression.IndexOf("+")!=-1 || strExpression.IndexOf("-")!=-1
    || strExpression.IndexOf("*")!=-1 || strExpression.IndexOf("/")!=-1)
   {
    strExpression=CalculateExpress(strExpression).ToString();
   }
   return strExpression;
  }
  
  private string GetExpType(string strExpression)
  {
   strExpression=strExpression.ToUpper();
   if (strExpression.IndexOf("SIN")!=-1)
   {
    return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("N")+1,strExpression.Length-1-strExpression.IndexOf("N")),EnumExpress.Sin).ToString();
   }
   if (strExpression.IndexOf("COS")!=-1)
   {
    return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("S")+1,strExpression.Length-1-strExpression.IndexOf("S")),EnumExpress.Cos).ToString();
   }
   if (strExpression.IndexOf("TAN")!=-1)
   {
    return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("N")+1,strExpression.Length-1-strExpression.IndexOf("N")),EnumExpress.Tan).ToString();
   }
   if (strExpression.IndexOf("ATAN")!=-1)
   {
    return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("N")+1,strExpression.Length-1-strExpression.IndexOf("N")),EnumExpress.ATan).ToString();
   }
   if (strExpression.IndexOf("SQRT")!=-1)
   {
    return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("T")+1,strExpression.Length-1-strExpression.IndexOf("T")),EnumExpress.Sqrt).ToString();
   }
   if (strExpression.IndexOf("POW")!=-1)
   {
    return CalculateExExpress(strExpression.Substring(strExpression.IndexOf("W")+1,strExpression.Length-1-strExpression.IndexOf("W")),EnumExpress.Pow).ToString();
   }
   return strExpression;
  }
 }
}

C# 逆波兰表达式解析公式 你是否遇到这样的需求:如何计算“1.0+3/2-tan(45)/(1+1)+Abs(-10)-floor(2.55)” 这一串字符串的值? 思路: 定义: 逆波兰表达式又叫做后缀表达式。在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表示。波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示表达式的方法,按此方法,每一运算符都置于其运... 阅读详情

相关推荐

【信息科学与工程学】【安全领域】第七十篇 负载均衡设备的主要算法01

每个服务器有一个对槽位的偏好排序, 调度器(表)需要为每个槽位分配一个服务器, 目标是整体上满足所有服务器的偏好(即均匀填充), 同时保持稳定性(变化小)。: 对于一个新到达的请求, 如果将其分配到当前有cj个请求(包括正在服务的)的服务器sj, 其期望等待时间为 (cj + 1) / μj。输入:服务器集群S={s1, s2, ..., sn}, 权重W={w1, w2, ..., wn}, 当前指针i。输出:选中的服务器sj。输入:服务器集群S, 各服务器当前活动连接数cj, 各服务器预设权重wj。

weixin_49199313的博客 524

.NET实现解析字符串表达式

一、引子·功能需求我们创建了一个 School 对象,其中包含了教师列表和学生列表。现在,我们需要计算教师平均年龄和学生平均年龄。//创建对象 School school = new School() { Name = "小菜学园", Teachers = new List<Teacher>() { new Teacher() {Name="波老...

farway000的博客 816

calcula-core:用.NET 5.0 C#编写的数学表达式解析器和计算器

钙核 Calcula的核心计算库。 工作正在进行中! 依存关系:

.Net表达式计算(公式) ,字符串转数学算式计算结果

【代码】.Net表达式计算(公式) ,字符串转数学算式计算结果。

小熊猫 653

基于VB.Net 编写的函数表达式计算器源代码

一款基于VB.NET编写的函数表达式计算器源代码。支持自由输入数学函数表达式运算。例如:可以输入运算式 Y = Int(25 * Sin(Ix)) + (Log(Ix) + Sqrt(65)),而后计算自变量Ix从1到1000的所有运算结果,并支持十六进制输出表示法,可以很直观地看出数学式在区间内的变化规律。

C# Cron表达式解析 .net

可以解析Cron表达式,个人有用希望你也有用。一个是例子,一个是代码实现,需要根据自己实现需求修改。

如何用Grokking Algorithms快速提升编程技能:面向初学者的终极指南

想要快速掌握编程算法核心概念吗?Grokking Algorithms项目为你提供了完美的学习路径!这个开源项目包含了《Grokking Algorithms》一书中所有算法的多种编程语言实现,是初学者学习算法的最佳资源。无论你是Python、JavaScript还是其他语言的开发者,都能在这里找到适合你的学习材料。😊 ## 🎯 Grokking Algorithms项目概览 Grokki

gitblog_00045的博客 504

NCalc:NCalc 是 .NET 的数学表达式解析器

计算器 NCalc 是 .NET 的数学表达式解析器。 NCalc 可以解析任何表达式并评估结果,包括静态或动态参数和自定义函数。 它是什么? Nalc 由创建,并在 MIT 许可下通过和。 可悲的是,该软件包已不再维护,这个原本很棒的软件中仍然存在一些问题。 我没有寻找另一个表达式解析器,而是试图纠正我可以用它解决的问题,并重新分发源代码以供社区使用(根据最初发布的许可证)。 非常欢迎问题和拉取请求来支持这项工作。 如果时间允许,我将尝试将 CodePlex 上的任何未解决问题转录到此存储库,以便可以正确跟踪和解决它们。 下面是对 NCalc 提供的功能以及如何实现它的示例的概览。 它有什么作用? 简单的表达式 Expression e = new [removed] " 2 + 3 * 5 " ); Debug . Assert ( 17 == e . Evaluate

.NET Flee 字符串表达式动态解析,怎么性能优化!!

Flee (支持 Net6.0, Net5.0, Netstandard2.1, Netstandard2.0)动态解析的框架是有几个的,个人先使用了DynamicExpresso,但是需求中是需要支持IF/ELSE的,DynamicExpresso中支持三目运算,可以代替IF/ELSE,需要对字符串表达式进行IF/ELSE到三目运算的转换才能使用,之后发现了Flee直接支持。DynamicExpresso和Flee相比较,个人感觉Flee的性能更好,支持的功能也比较多。

Maybe_ch的博客 1520

基于PLC智能立体车库控制系统设计

摘要 本系统设计以三层立体车库为研究对象,通过对立体车库的原理分析、动作流程设计和一系列的软硬件设计,达到立体车库自动化控制的目的。系统采用可编程控制器作为立体车库控制系统的控制单元,实现该系统的工艺要求,通过程序仿真调试,完成系统的各种动作要求,达到自动控制的目的。系统设计分为总体设计、硬件设计以及软件设计。按照立体车库控制系统的控制策略进行图纸设计;重点分析工艺流程图,对立体车库控制系统进行程序编译和MCGS上位机调试,通过系统的调试和修改,达到了基本控制的要求。系统设计明确了工艺要求,确定

DX884164131的博客 3600

解决西门子Step 7 basic 找不到许可证问题

你在使用博图软件是否遇到过Step 7 basic 找不到许可证的问题呢!不言怕,今天我就来告诉你该如何处理吧!看步骤: 1.删除原授权的License: 打开Automation License Manager应用,然后我们可以发现仅有的License Key前面有一个时钟,说明它已经过期不可用,我们就要去寻求新的Key. 打开“我的电脑”,选择C盘,点击上方查看 点击选项–>查看 然...

让技术没有门槛 14万+

.net中处理数学表达式

最近需要计算带参数的数学表达式,比如“X+Y+10+sin(Y)”之类的的公式,原来用VC的一个计算表达式的类,挺方便的,但是在网上找.net居然没找了好久。不过还是找到两个,一个是这个http://download.csdn.net/source/346496上面这个用起来还是比较方便比较快下面这个是老外写的,动态编译,可以学习,但是处理起来比较慢 using Sys

博客搬往 http://begtostudy.cnblogs.com 1471

红日-VulnStack靶场-ATT&CK(二):从Weblogic漏洞到域控渗透实战

本文详细解析了红日安全团队VulnStack靶场中从Weblogic漏洞到域控渗透的完整攻击链。通过实战演示Weblogic反序列化漏洞利用、Cobalt Strike持久化控制、域内信息收集及PsExec横向移动等关键技术,复现了企业内网渗透的典型场景,并提供了防御建议。

tgb3456789的博客 936

计算器核心解析算法

文章目录1 计算器程序界面分析2 计算器界面程序实现 1 计算器程序界面分析 程序界面如下: 界面设计: 定义组件间的间隔: Space = 10px 定义按钮组件的大小: Width = 40px,Height = 40px 定义文本框组件的大小: Width = 5 * 40px + 4 * 10px, Height = 30px 对于Qt应用程序开发: GUI应用...

木子皿--啥都不会的菜鸟 1561

筹码峰五句口诀,看懂主力的秘密动作!(附实战图示)

筹码图的价值在于,它不像K线那样容易造假。主力可以骗线,但骗不了筹码分布。主力在不在;是吸筹还是出货;接下来是变盘还是震荡。这五句口诀可以说是“筹码阅读的入门圣经”:单峰坚挺变盘在即,双峰对垒高抛低吸;上峰不移主力在跑,多峰林立行情不止;下峰不移不离不弃,筹码识庄稳中取利!📌市场从来不是靠猜,而是靠看清。筹码,就是主力最真实的痕迹。如果你想学会提前布局、跟庄不被甩,学会看筹码峰——这一步必须打牢!

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1166

Ultralytics YOLOv8 英伟达™ Jetson®处理器部署

英伟达™(NVIDIA®)Jetson 是一系列嵌入式计算板卡,旨在为边缘设备带来加速的 AI(人工智能)计算。这些小巧而功能强大的设备围绕英伟达™(NVIDIA®)的GPU架构打造,能够直接在设备上运行复杂的人工智能算法和深度学习模型,而无需依赖云计算资源。Jetson 板卡通常用于机器人、自动驾驶汽车、工业自动化和其他需要在本地以低延迟和高效率执行人工智能推理的应用中。此外,这些板卡基于 ARM64 架构,与传统 GPU 计算设备相比运行功耗更低。英伟达™(NVIDIA®)JetPack SDK。

机器人控制与仿真应用 3876

公式解析器开源项目整理

前段日子师兄让我整理开源的公式解析器项目,我到网上查了两天,对大部分有人维护的开源项目进行了整理和总结:现在记在此处。 开源项目名称 描述 缺点 Jeval 在运行时解析计算静态和动态表达式;支持数学,布尔,字符串,函数表达式;支持大部分的数学和布尔运算符;支持自定义函数;支持嵌套函数;支持解析;支持自定义变量解析器; 官网:http://j

novelly的专栏 6284

osg中显示3dtiles和cesiumIon

如下图为CesiumTilesetNode数据更新相关代码,将OSG对应的ViewMatrix、ProjectionMatrix和窗口信息传递给tileset->updateView()实现Cesium-native的场景更新。整体结构,其中 CesiumTilesetNode依赖Cesium3DTilesSelection::Tileset,实现数据的更新以及确定需要绘制的节点。1.1 CesiumNative3DTileslayer图层。

CPWWHSU的博客 889

.net 字符串转公式 ——利用表达式引擎Eval Expression

项目中,公式是以字符串形式存储到数据库中,如何将字符串转为公式并进行计算? 公式示例  a.price*a.account*b.quantity 解决方案:利用Eval Expression插件 插件官网:http://eval-expression.net/ 案例参考: http://www.cnblogs.com/asxinyu/p/dotnet_Opensource_project...

hhhhhhenrik的博客 4800

2026 企查查/天眼查:IP频率限制 + 验证码策略,企业工商数据采集实战

企业工商数据采集技术解析与解决方案 本文深度剖析了2026年企查查和天眼查平台的反爬机制与技术对抗方案。主要内容包括: 反爬机制分析: 采用JA4+ TLS指纹识别、极验v6验证码等多层防护 IP限制策略严格区分未登录/普通/VIP账号 精准识别并封禁数据中心IP 核心解决方案: 构建高可用住宅代理池,动态轮换真实用户IP 基于YOLOv8的验证码缺口识别技术(准确率99%) 分布式架构设计,支持千万级数据采集 多账号池管理与行为模拟技术 技术亮点: 动态住宅IP池实现1%以下封禁率 Playwright浏

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1328

C# 从数秒到毫秒:MySQL+Redis百万数据优化实战全解析

在处理百万级数据时,传统单体数据库常面临查询效率低下、数据库负载过高和用户体验差等问题。为解决这些性能瓶颈,可以采用MySQL分库分表、Redis缓存和异步统计的组合策略。 数据库分片:通过水平分表和分库实现,将单表数据分散到多个物理表或数据库实例中,降低单点负载。 Redis缓存:利用Redis缓存高频数据,减少数据库查询压力,提升响应速度。 异步统计:通过消息队列(如RabbitMQ)解耦统计任务,后台处理非实时任务,避免阻塞主流程。 这些优化策略能够显著提升系统性能,确保在高并发和大数据量场景下的稳定

墨夶的博客 852

.net 常用格式化公式

{0:C}  货币; {0:D4}由0填充的4个字符宽的字段中显示整数; {0:000.0}四舍五入小数点保留第几位有效数字; {0:N2}小数点保留2位有效数字;{0:N2}%   小数点保留2位有效数字加百分号; {0:D}长日期;{0:d}短日期;{0:yy-MM-dd}   例如07-3-25;;{0:yyyy-MM-dd}  例如2007-3-25

jrsnd的专栏 617

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

\(^_^)/ 表达式解析器(MVEL)

Jeval 在运行时解析计算静态和动态表达式;支持数学,布尔,字符串,函数表达式;支持大部分的数学和布尔运算符;支持自定义函数;支持嵌套函数;支持解析;支持自定义变量解析器; 官网:http://jeval.sourceforge.net 不支持嵌套变量   jexel 处理大部分的数学公式和字符串,通过继承接口来实现个人所需的运算;支持自定义变量解析器;该项目一直在更新,最近一次...

yanguz的专栏 2642

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

下一篇: 如何通过动态生成Html灵活实现DataGrid分类统计的界面显示功能
activeandbadboy
博客等级 码龄24年 0粉丝 2原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值