添加了另一个示例。
我有一个数学表达式,如cos(pi * cos(pi * sin(pi * y))),我想解决它。
我认为解析它的最佳方法是从字符串的结尾开始。
所以,在上面的表达式中:
我将添加另一个表达式作为示例: COS(PI *(平均(X,X)* Y))
这应该像这样评估:
你怎么看?你能帮我实现一下代码吗?
提前致谢
答案 0 :(得分:3)
我有一个数学表达式,如cos(pi * cos(pi * sin(pi * y))) 我想解决它。
不,你想评估它。求解告诉你某些事情的真实条件。评估它只会给你一个结果值。
我认为解析它的最佳方法是从字符串的结尾开始。
解析像这样的表达式的传统方法是使用递归下降。它更通用,更容易实现。控制流程看起来像这样:
cos
(
A ...
其中 A = pi
*
cos
(
B ......
其中 B = pi
*
sin
(
C ...
其中 C = pi
* y
现在您可以评估 pi * y
,并返回 C 的值
...现在您已经 C ,您可以评估pi * sin(C)
并返回 B 的值
...现在您拥有 B 的值,您可以评估pi * cos(B)
,将值返回为 A
...现在您拥有 A 的价值,您可以评估cos(A)
,然后就完成了。
这正是C表达式cos(M_PI * cos(M_PI * sin(M_PI * y)))
的工作方式(假设π的常见但非标准常量)。
评估大致从右到左(实际上是从内到外),但仍然从左到右阅读。为了清晰起见,我们刚刚标记了临时值。
这种控制流程通常简单地变成了像
这样的树[cos of _]
|
[pi * _]
|
[cos of _]
|
[pi * _]
|
[sin of _]
|
[pi * y]
但显然你可以只评估一次结果,除非你需要保存树以供日后使用。 (注意这个不平衡的树仍然是一棵树,它只是因为表达式嵌套的方式而退化)。
......您如何看待它?
您的解决方案的问题在于它会破坏不同的嵌套结构,例如
cos( sin((pi * x) + y) + sin(y + (pi * x)) )
不能简单地从右到左进行评估。
你能帮我实现一下代码吗?
将字符串处理(标记化)与解析和评估分开。单独推理字符串处理和数学会更容易。
答案 1 :(得分:0)
已编辑:基本案例改进。
这只是一些伪代码,但这个想法应该有效:
int ParseAndCalculate(string input)
{
if (input.DoesConvertToSomeIntegerWork())
return input.ConvertToSomeInteger();
string actionRequired = GetActionFromString(input, "(");
int tempIndex = input.LocationOfFirst("(");
int tempResult = ParseAndCalculate(input, tempIndex, input.Length -1);
tempResult = PerformRequiredAction(tempResult, actionRequired);
return tempResult;
}
不确定你应该在基本情况下返回什么。也许弄清楚那里的实际价值是什么?
答案 2 :(得分:0)