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 ...
随机推荐
- Go 命令之 godep
本文参考:http://www.cnblogs.com/me115/p/5528463.html#h20 http://studygolang.com/articles/4385 关于Godep 发现 ...
- DWZ集成的xhEditor编辑器浏览本地图片上传的设置
有关xhEditor的文件上传配置官方文档链接:http://i.hdu.edu.cn/dcp/dcp/comm/xheditor/demos/demo08.html 一.xhEditor图片上传的配 ...
- ZooKeeper学习第五期--ZooKeeper管理分布式环境中的数据
引言 本节本来是要介绍ZooKeeper的实现原理,但是ZooKeeper的原理比较复杂,它涉及到了paxos算法.Zab协议.通信协议等相关知识,理解起来比较抽象所以还需要借助一些应用场景,来帮我们 ...
- pandas 数据索引与选取
我们对 DataFrame 进行选择,大抵从这三个层次考虑:行列.区域.单元格.其对应使用的方法如下:一. 行,列 --> df[]二. 区域 --> df.loc[], df.ilo ...
- scrapy 爬取自己的博客
定义项目 # -*- coding: utf-8 -*- # items.py import scrapy class LianxiCnblogsItem(scrapy.Item): # define ...
- 使用ObjectAnimator设置动画
ObjectAnimator是ValueAnimator的子类,他本身就已经包含了时间引擎和值计算,所以它拥有为对象的某个属性设置动画的功能.这使得为任何对象设置动画更加的容易.你不再需要实现 Val ...
- [matlab]改变矩阵的大小并保存到txt文件
要完成的任务是,加载一个保存在txt文件中的矩阵, 并把它扩大10倍,并且要再次保存回去 %加载txt文件 >load('Matrix.txt'); %扩大10倍 repmat(Matrix,r ...
- Chrome扩展开发之三——Chrome扩展中的数据本地存储和下载
目录: 0.Chrome扩展开发(Gmail附件管理助手)系列之〇——概述 1.Chrome扩展开发之一——Chrome扩展的文件结构 2.Chrome扩展开发之二——Chrome扩展中脚本的运行机制 ...
- replace 替换全部的正确姿势
本文同步自我的个人博客:http://www.52cik.com/2015/11/06/replace-all.html 关于字符串替换问题,其实是个很简单的问题,但却也不那么简单,至少对于很多新手而 ...
- php模式设计之 观察者模式
这是我写的<php模式设计>的第五篇.前面的四篇在不断学习不断加深认识,到了今天再看观察者模式,觉得非常容易理解.这也许就是我们积少成多的结果吧.希望还是能够不断进步. 开篇还是从名字说起 ...