C#实现eval 进行四则运算
昨天在园子里看到有园友,写了相同标题的一篇文章。重点讲的是中缀表达式转换为后缀表达式的算法,但是实现的四则运算 有bug。其实我没看之前也不懂什么是 中缀和后缀表达式,之前有用过js eval 内置函数,后边一想貌似C#中是没有这样的一个函数,加上自己也没事,就试着自己写了下 这个所谓的四则运算。
我没有研究计算机是怎么来进行四则运算的,我只是按自己的想法来实现 对 6-2*(5-3)+6/2*(6-3+3)/2 这样一个随意组合的四则运算表达式。
我的思路是样的:
<1> 先递归把表达式中的括号中的表达式给算出来,然后将值将之替换
#region 计算括号中的表达式
/// <summary>
/// 获取括号中的计算表达式
/// (递归)
/// </summary>
/// <param name="express"></param>
public void GetBraceExpress(ref string express)
{
int leftBraceMaxIndex = -;
IList<int> rightBraceMinIndexs = new List<int>();
for (int i = ; i < express.Length; i++)
{
if (express[i].ToString() == "(")
{
leftBraceMaxIndex = i;
}
if (express[i].ToString() == ")")
{
rightBraceMinIndexs.Add(i);
}
}
if (leftBraceMaxIndex != - && rightBraceMinIndexs.Count > )
{
int rightBraceIndex = ;
foreach (var item in rightBraceMinIndexs)
{
if (item > leftBraceMaxIndex)
{
rightBraceIndex = item;
break;
}
} string braceExpress = express.Substring(leftBraceMaxIndex, rightBraceIndex - leftBraceMaxIndex + );
double result = CalcExpress(braceExpress.TrimStart('(').TrimEnd(')')); //计算()中的表达式
express = express.Replace(braceExpress, result.ToString()); //结果替换 ()表达式
if (express.IndexOf("(") != - && express.IndexOf(")") != -)
{
GetBraceExpress(ref express);
return;
}
}
}
#endregion #region 计算表达式
/// <summary>
/// 计算表达式
/// </summary>
/// <param name="express">表达式</param>
/// <returns>表达式结果</returns>
public double CalcExpress(string express)
{
List<double> numbers = new List<double>(); //表达式中的数字
List<char> operaters = new List<char>(); //表达式中的操作符
int tempIndex = ;
for (int i = ; i < express.Length; i++)
{
if (!char.IsNumber(express[i]) && char.IsNumber(express[i - ]) && i > )
{
if (tempIndex != )
tempIndex = tempIndex + ;
numbers.Add(double.Parse(express.Substring(tempIndex, i - tempIndex)));
operaters.Add(express[i]);
tempIndex = i;
}
}
numbers.Add(double.Parse(express.Substring(tempIndex + , express.Length - tempIndex - )));
//开始计算
double result = ;
if (operaters.Count == )
{
return double.Parse(express);
}
else
{
CalcMultiplyDivide(numbers, operaters); //计算乘除
result = CalcAddSubduction(numbers, operaters); //计算加减
}
return result;
}
#endregion
<2> 递归将 没有括号的表达式中的乘除计算,将结果替换 乘除表达式
#region 计算乘除
/// <summary>
/// 递归计算表达式中的乘/除运算
/// </summary>
/// <param name="numbers">表达式中的数字集合</param>
/// <param name="operaters">操作符集合</param>
public void CalcMultiplyDivide(List<double> numbers, List<char> operaters)
{
for (int i = ; i < operaters.Count; i++)
{
bool temp = false;
double n = ;
if (operaters[i] == '*')
{
n = numbers[i] * numbers[i + ];
temp = true;
}
else if (operaters[i] == '/')
{
n = numbers[i] / numbers[i + ];
temp = true;
}
if (temp)
{
operaters.RemoveAt(i);
numbers.RemoveRange(i, );
numbers.Insert(i, n);
CalcMultiplyDivide(numbers, operaters);
break;
}
}
}
#endregion
<3> 递归算加减,直到表达式中没有操作符,然后返回结果。
#region 计算加减
/// <summary>
/// 递归计算加减
/// </summary>
/// <param name="numbers">表达式中的数字集合</param>
/// <param name="operaters">操作符集合</param>
/// <returns>计算的结果</returns>
public double CalcAddSubduction(List<double> numbers, List<char> operaters)
{ for (int i = ; i < operaters.Count; i++)
{
bool temp = false;
double n = ;
if (operaters[i] == '+')
{
n = numbers[i] + numbers[i + ];
temp = true;
}
else if (operaters[i] == '-')
{
n = numbers[i] - numbers[i + ];
temp = true;
}
if (temp)
{
operaters.RemoveAt(i);
numbers.RemoveRange(i, );
numbers.Insert(i, n);
CalcAddSubduction(numbers, operaters);
break;
}
}
double result = ;
if (operaters.Count == )
result = numbers[];
return result;
}
#endregion
这就可以实现像js eval 方法一样对一个四则运算表达式 计算了。这只是按我自己的思路来实现的,没有考虑性能啊什么的,如大家有什么好的法子,一起讨论下。
附上demo:http://files.cnblogs.com/joey0210/Calc.rar
C#实现eval 进行四则运算的更多相关文章
- C#实现eval 进行四则运算(有码)
在JavaScript中实现四则运算很简单,只需要调用eval函数就行了,但是不知道什么原因万能的.NET却没有封装这个函数~ 在这里为大家封装了一个C#版本的eval函数,具体的设计参考了<大 ...
- C#实现eval
C#实现eval 进行四则运算(有码) 在JavaScript中实现四则运算很简单,只需要调用eval函数就行了,但是不知道什么原因万能的.NET却没有封装这个函数~ 在这里为大家封装了一个C#版 ...
- 软件工程(FZU2015)增补作业
说明 张老师为FZU软件工程2015班级添加了一次增补作业,总分10分,deadline是2016/01/01-2016/01/03 前11次正式作业和练习的迭代评分见:http://www.cnbl ...
- 软件工程(FZU2015) 增补作业
SE_FZU目录:1 2 3 4 5 6 7 8 9 10 11 12 13 说明 张老师为FZU软件工程2015班级添加了一次增补作业,总分10分,deadline是2016/01/01-2016/ ...
- C#版的eval,C#Light开源嵌入式脚本,unity热更新不再愁
目前最新版本AlphaV0.06 完全的c#语法,可用于一切能运行C#的场合,wp windows xamarin mono asp.net unity3d 内嵌了int uint bool stri ...
- [置顶] js综合应用:表格的四则运算
在做调查问卷的过程中,遇到一个表格的统计问题,算是需要些js方面的综合知识,所以记录下来. 在上次完成了基本的求和的基础上,添加了基本的加减乘除四则运算. 基本需求简化后如下: 对应的htm了为: & ...
- 结对编程1---基于Flask的四则运算题目生成器
项目代码地址 / WEB应用地址 / 合作伙伴iFurySt博文链接 需求分析 本次程序是基于原有的控制台四则运算器的基础上,改成WEB的形式,同时还增加了一些新的功能.同时因为交互方式的改变,代码也 ...
- Python实现简单的四则运算
GitHub 项目地址 https://github.com/745421831/-/tree/master PSP PSP2.1 Personal Software Process Stages 预 ...
- 小学生噩梦——四则运算题库(python 全功能实现)
Github: https://github.com/holidaysss 小组:龙天尧(代码实现),林毓植(浮点转分数函数,代码审查) PSP2.1 Personal Software Proces ...
随机推荐
- 学习心得:《十个利用矩阵乘法解决的经典题目》from Matrix67
本文来自:http://www.matrix67.com/blog/archives/tag/poj大牛的博文学习学习 节选如下部分:矩阵乘法的两个重要性质:一,矩阵乘法不满足交换律:二,矩阵乘法满足 ...
- Linux 网络编程二(Socket创建)
TCP通信 一个程序使用套接字需要执行4个步骤. --分配套接口和初始化 --连接 --发送或接收数据 --关闭套接字 涉及到的调用包括socket.bind.listen.connect(阻塞线程) ...
- U3D assetbundle打包
using UnityEngine; using System.Collections; using UnityEditor; //此脚本不一定要放于editor目录下,经测试,放于其它地方也可以 p ...
- 在Sql Server 中使用正则表达式
CREATE FUNCTION dbo.find_regular_expression ( ), --需要匹配的源字符串 ), --正则表达式 --是否区分大小写,默认为false ) RETURNS ...
- 使用ajax跨域withCredentials的作用
默认情况下,跨源请求不提供凭据(cookie.HTTP认证及客户端SSL证明等).通过将withCredentials属性设置为true,可以指定某个请求应该发送凭据.如果服务器接收带凭据的请求,会用 ...
- main函数中argc和argv含义
在main函数中经常可以看到int main(int argc, char ** argv)的函数头,这里的形参int argc, char ** argv究竟是啥含义呢? &1 int ar ...
- Android完美禁用Home键
重写Activity的onAttachedToWindow 方法 @Override public void onAttachedToWindow() { System.out.println(&qu ...
- 说说C#中IList与List区别
首先IList 泛型接口是 ICollection 泛型接口的子代,并且是所有泛型列表的基接口. 它仅仅是所有泛型类型的接口,并没有太多方法可以方便实用,如果仅仅是作为集合数据的承载体,确实,ILis ...
- iOS从App跳转至系统设置菜单各功能项的编写方法讲解
跳到系统设置里的WiFi界面 info里面设置: 在项目中的info.plist中添加 URL types 并设置一项URL Schemes为prefs,如下图 代码: 复制代码 代码如下: NSUR ...
- 安装.NET CORE
需要安装两个包 https://github.com/dotnet/cli 1. .NET Core Installer 2. .NET Core SDK Installer