C 数学表达式的解析

C 数学表达式的解析,c,algorithm,parsing,data-structures,C,Algorithm,Parsing,Data Structures,(在c90中)(linux) 输入: sqrt(2 - sin(3*A/B)^2.5) + 0.5*(C*~(D) + 3.11 +B) a b /*there are values for a,b,c,d */ c d cos(2 - asin(3*A/B)^2.5) +cos(0.5*(C*~(D)) + 3.11 +B) a b /*there are values for a,b,c,d */ c d sqrt(2 - sin(3*A/B)^2.5)/(0.5*(C*~(D)

(在c90中)(linux)

输入:

sqrt(2 - sin(3*A/B)^2.5) + 0.5*(C*~(D) + 3.11 +B)
a
b   /*there are values for a,b,c,d */
c
d
cos(2 - asin(3*A/B)^2.5) +cos(0.5*(C*~(D)) + 3.11 +B)
a
b   /*there are values for a,b,c,d */
c
d
sqrt(2 - sin(3*A/B)^2.5)/(0.5*(C*~(D)) + sin(3.11) +ln(B))
 /*max lenght of formula is 250 characters*/
a
b   /*there are values for a,b,c,d */
c   /*each variable with set of floating numbers*/
d
输入:

sqrt(2 - sin(3*A/B)^2.5) + 0.5*(C*~(D) + 3.11 +B)
a
b   /*there are values for a,b,c,d */
c
d
cos(2 - asin(3*A/B)^2.5) +cos(0.5*(C*~(D)) + 3.11 +B)
a
b   /*there are values for a,b,c,d */
c
d
sqrt(2 - sin(3*A/B)^2.5)/(0.5*(C*~(D)) + sin(3.11) +ln(B))
 /*max lenght of formula is 250 characters*/
a
b   /*there are values for a,b,c,d */
c   /*each variable with set of floating numbers*/
d
输入:

sqrt(2 - sin(3*A/B)^2.5) + 0.5*(C*~(D) + 3.11 +B)
a
b   /*there are values for a,b,c,d */
c
d
cos(2 - asin(3*A/B)^2.5) +cos(0.5*(C*~(D)) + 3.11 +B)
a
b   /*there are values for a,b,c,d */
c
d
sqrt(2 - sin(3*A/B)^2.5)/(0.5*(C*~(D)) + sin(3.11) +ln(B))
 /*max lenght of formula is 250 characters*/
a
b   /*there are values for a,b,c,d */
c   /*each variable with set of floating numbers*/
d
正如您可以看到的,输入中的中缀公式取决于用户。 我的程序将采用公式和n元组值。 然后计算a、b、c和d的每个值的结果。 如果你想知道我在说什么;程序的结果是图形。 /有时,我想我会接受输入并存储在字符串中。 另一个想法是“我应该在结构中存储公式” 但我不知道我该怎么做 基于结构的代码。/

真的,我不知道如何将公式存储在程序代码中以便 我能做好我的工作。 你能给我看看吗

/* a,b,c,d is letters
 cos,sin,sqrt,ln is function*/
您需要编写一个标记来标记输入(将其分解为其组成部分——运算符、标点符号、标识符等)。不可避免地,您将得到一些令牌序列


之后,有许多方法来评估输入。最简单的方法之一是使用将表达式转换为后缀(后缀表达式的计算很容易,大写字母为E)。

此外,您还应该查看SO的帖子和其他关于二叉树的帖子。使用树结构来实现这一点。作为中缀进行遍历以进行计算。对于树型问题有一些很好的答案

如果您需要将其存储(作为文件的持久性),我建议使用XML。解析XML应该让您真正体会到您的作业是多么简单。

您应该查找“抽象语法树”和“表达式树”以及“词汇分析”、“语法”、“解析”和“编译器理论”。阅读文本输入并从中获得意义对于大多数事情来说都是相当困难的(尽管我们经常试图确保我们有简单的输入)

生成解析器的第一步是写下输入语言的语法。在本例中,您的输入语言是一些数学表达式,因此您可以执行以下操作:

expr => <function_identifier> ( stmt )
        ( stmt )
        <variable_identifier>
        <numerical_constant>

stmt => expr <operator> stmt
还有一些工具可以为此生成代码<其中的code>lex与解析器生成程序yacc高度集成,但由于您正在努力学习,您也可以用C编写自己的标记器/词法分析代码

完成所有这些之后(可能需要花费相当长的时间),您需要让解析器构建一棵树来表示输入的表达式和语法。在表达式求值的简单情况下(比如编写一个简单的命令行计算器程序),您可以让解析器在处理输入时对公式求值,但在您的情况下,据我所知,您需要创建一个树(或反向波兰表示,但我认为树更容易)


然后,在读取变量的值之后,您可以遍历树并计算实际数。

可能最简单的方法是使用嵌入式语言,如Lua或Python,这两种语言的解释器都是用C编写的。不幸的是,如果使用Lua,则必须将二进制操作转换为函数调用,在这种情况下,使用Python可能更容易。所以我会沿着这条路走

如果您只想将结果输出到控制台,这非常简单,您甚至不必深入研究Python嵌入。因此,您只需用Python编写一行程序即可输出值

以下是您可以使用的Python代码:

exec "import math;A=<vala>;B=<valb>;C=<valc>;D=<vald>;print <formula>".replace("^", "**").replace("log","math.log").replace("ln", "math.log").replace("sin","math.sin").replace("sqrt", "math.sqrt").replace("cos","math.cos")
您可以在此处查找有关在C中嵌入Python的更多信息:

如果您需要在程序中使用计算结果,有几种方法可以从Python中读取该值,但您必须自己阅读它们。

查看此帖子:
它使用ANTLR库解析数学表达式,这一个具体使用JavaScript输出,但是ANTLR有许多输出,如java、露比、C++、C,并且你应该能够在任何输出语言中使用该语法。

你确实需要更好地解释你自己。@ Matsemann是的,这是你重新提问时的行为。不管帖子有多旧,坏标签都是坏标签。我认为那是作弊;-)。在Python中做这件事比在C中更容易做到这一点,但是在C中实现表达式计算器既有趣又有趣(我可以在C中实现,但是我有C++,600行代码,后来我知道了更多关于表达式如何被评估<代码>:-))。如果目标是了解表达式评估,我同意;否则,如果这只是一个中间步骤,那么这将更容易,也不容易出现错误。您可以将其与使用标准库功能进行比较。当你被要求自己写的时候,使用它是欺骗;否则,这是有道理的但是,是的,我同意这可能是一个有趣的学习经历,我还没有开始。一个有效的观点:既然OP没有说他的目的是什么,这是一个解决方案的好主意(+1)。