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 ...
随机推荐
- Maximal Square
Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and ret ...
- TDD开发感悟
由于公司要实现TDD形式的开发,所以准备了一下,准备在后续的项目中,投入到TDD的怀抱中. 在找一些参考书目的过程中,偶遇<测试驱动开发的艺术>这本书,书中的编码为JAVA派系,但是书的内 ...
- CSS 实现加载动画之二-圆环旋转
上次简单的介绍了下如何用代码实现菊花旋转的加载动画,动画点击,这次继续我们的动画系列,实现另外一种加载动画,圆环旋转.与上次不同的是,菊花旋转是通过改变元素透明度来实现动画,这次因为考虑到元素叠加,加 ...
- Fragment中监听onKey事件,没你想象的那么难。
项目中越来越多的用到Fragment,在用Fragment取代TabHost的时候遇到了一个问题,我们都知道,TabHost的Tab为Activity实例,有OnKey事件,但是Fragment中没有 ...
- Android 长按Listview显示CheckBox,实现批量删除。
ListView实现的列表,如果是可编辑,可删除的,一般都要提供批量删除功能,否则的话,一项一项的删除体验很不好,也给用户带来了很大的麻烦. 实现效果图 具体实现代码 select.xml 主布局文件 ...
- LINUX第五次实验报告
北京电子科技学院(BESTI) 实 验 报 告 课程:信息安全系统设计基础 班级: 201353 姓名:刘世鹏 郝爽 学号:2013530 ...
- 模态窗口插件之Jbox
$.jBox.tip("报损数量不能大于库存数!", 'error'); $.jBox.tip("请选择要报损的产品", "warn"); ...
- form表单用ge方式提交时ie显示中文参数乱码
有网友说 通过给form表单添加accept-charset="gb2312"和 onsubmit="document.charset='gb2312'" 但这 ...
- 线段树好题(2004集训队林涛PPT中的3题)
1.snake:主要是要意识到全局的可能连法只有一种= =(略坑,题目的最小长度是唬人的……),所以关键就是能否构造出符合题意的图,可以考虑搜索解决,搜出一个就OK了,但是会发现那些满足条件中线段在非 ...
- 第三十四课:jQuery Deferred详解2
上一课主要分析了jQuery1.51版本的jQuery Deferred.在jQuery1.6中,jQuery Deferred添加了两个方法,always,pipe. always用来添加回调,无论 ...