C#实现复杂表达式的计算

C#实现复杂表达式的计算

1、问题描述:
设计一个能进行+ - * /,同时支持sin、cos、abs等函数的计算器,对于表达式中未声明的变量,随机生成一个0~9的数,其中x是默认变量。
例如:
1)、-1+a+0.12
2)、asin(bx+c)
3)、asin(b*x+c^2)+abs(3+x)/(s*floor(x))+a

2、解决思路:
拆分与标准化表达式------》计算表达式的值-------》得出结果

首先
将表达式看成是由若干Item项之和构成的,即:
Expression=Item1+Item2+…+Itemn
其中,Item由若干个因子Factor的乘积或商构成。
Factor可以是常数、变量、运算函数、带括号的表达式。

表达式拆分的解决策略:
设置一个变量couples用来记录当前检索到的未成对括号的对数,初始值为0;当couples=0且当前检索的字符temp=’+‘或者temp=’-'时,就表示是一个Item项的结束,将此前已检索的字符串赋给Item,同时置另一个Item项的初值为temp,即Item+=temp;以此进行下去,直至检索结束。最后一个Item项的值为结束前已检索的字符串。
例如:
表达式asin(b*x+c^2)+abs(3+x)/(s*floor(x))+a拆分后得
Item1=asin(b*x+c^2)
Item2=+abs(3+x)/(s*floor(x))
Item3=+a

其次
将每个Item项标准化,例如Item项asin(bx+c),标准化后a*sin(b*x+c)。
标准化时,默认一连串字母中在最后才有可能出现运算函数,此时采用的策略是循环匹配,若匹配成功则表明这一连串字母代表一个运算函数,否则,这一连串字母中的第一个是变量,剩下的字母再进行,直至匹配成功或剩下字母的个数为零。
当遇到表达式(1+2)(1+3),标准化后(1+2)*(1+3)。即当前字符为),且下一个字符为(时,要在中间添加一个*。

最后
计算每一个Item项的值,最后将每个Item项的值相加。

每一个item项的计算:用栈来实现
将Item项中数值与运算符分别压入数据栈和运算符栈中,将运算符压入运算符栈中需注意:
(1)、若栈为空,则直接将运算符压入
(2)、若栈不为空,且将要压入的元素为+或者-,则依次将运算符退栈并取出数据栈的所需元素个数进行相应的运算同时将运算结果压入数据栈中,直至运算符栈为空。
(3)、若栈不为空,且将要压入的元素为*、/,则依次将运算符退栈并取出数据栈的所需元素个数进行相应的运算同时将运算结果压入数据栈中,直至运算符栈为空或者栈顶元素为+或者-。
(4)、若栈不为空,且将要压入的元素为^或者sin等运算函数,则依次将运算符退栈并取出数据栈的所需元素个数进行相应的运算同时将运算结果压入数据栈中,直至运算符栈为空或者栈顶元素为+、-、*、/。
(5)、若将要压入的元素为(,则直接压入栈中。
(6)、若将要压入的元素为),则依次将运算符退栈并取出数据栈的所需元素个数进行相应的运算同时将运算结果压入数据栈中,直至栈顶元素为(,并将栈顶元素(退出。
注意:
为了处理负数数据的情况,采用的策略是,初始化数据栈的同时压入一个数据0。表达式处理结束后,数据栈的栈顶元素即为该Item项的值。

3、代码实现
由于代码量比较大,所以在这里就不再展示了。完整代码已上传至github,请有需要的自行上github浏览或下载。
链接:https://github.com/auroraZHONG/expression.git
正确打开路径:
viewcode------>Consoleapp3------->Program.cs

4、运行结果
在这里插入图片描述

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#的lambda达式是一种简洁而强大的语法形式,用于定义匿名函数。它的语法结构类似于= > 运算符,左侧是参数列,右侧是达式或语句块。 Lambda达式可以用于多种情况,比如作为参数传递给函数,定义委托类型,或在LINQ查询中使用。它可以代替繁琐的匿名方法或命名的方法,使代码更加简洁和易读。 在C#中,lambda达式可以分为两种类型:达式Lambda和语句Lambda。达式Lambda是指只有一个达式的lambda,它只能包含一个达式并返回其结果。 例如,下面的代码演示了如何使用达式Lambda来定义一个匿名函数并进行计算: ``` Func<int, int> func = x => x * 4; int result1 = func(5); //[1] ``` 这段代码定义了一个接受一个int类型参数并返回int类型结果的函数。通过达式Lambda,我们将输入的参数乘以4并返回结果。然后,我们可以通过调用func方法并传入参数5来获得计算结果result1。 此外,达式Lambda的主体还可以包含方法的调用。例如,我们可以在达式Lambda中调用其他方法,如下所示: ``` func = x => x * Add(3, 2); int result2 = func(5); //[1] ``` 在这个例子中,我们在达式Lambda中调用了Add方法,并将其结果与输入参数相乘。同样,我们可以通过调用func方法并传入参数5来获得计算结果result2。 总的来说,C#的lambda达式是一种方便而灵活的方式来定义匿名函数,并能简化代码和提高可读性。通过使用lambda达式,我们可以更加简洁地示函数逻辑和处理复杂的数据操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [C# Lambda达式](https://blog.csdn.net/qq_39847278/article/details/127525222)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值