受recent TED talk的启发,我想写一小段教育软件。研究人员创建了一些名为“Siftables”的小型微型计算机。
(来源:ted.com)
[David Merril, inventor - with Siftables in the background.
]
他使用了很多块应用程序,但我最喜欢的是每个块都是数字或基本操作符号。然后,您可以在一行中重新排列数字块或操作符号,它将在另一个可屏蔽块上显示答案。
所以,我决定要在有限的范围内实施“数学Siftables”的软件版本,作为我正在参加的CS课程的最终项目。
解析和解释一串数学表达式的普遍接受的方法是什么,如果它们有效,执行操作?
这是我应该实现完整解析器/词法分析器的情况吗?我认为解释基本的数学表达式将是计算机科学中的一个半常见问题,所以我正在寻找正确的方法来解决这个问题。
例如,如果我的Math Siftable阻止排列如下:
[1
][+
][2
]
这将是一个有效的序列,我将执行必要的操作以达到“3”。
但是,如果孩子要将几个操作块拖到一起,例如:
[2
][\
][\
][5
]
显然无效。
最终,我希望能够使用用户可以拖动的块来解析和解释任意数量的操作链。任何人都可以向我解释或指向我解析基本数学表达式的资源吗?
我希望尽可能多地使用与语言无关的答案。
答案 0 :(得分:3)
您可以查看Shunting Yard Algorithm。链接的维基百科页面有大量信息,并链接到算法的各种示例。
基本上,给定中缀数学符号的表达式,它会返回AST或反向波兰表示法,无论您的偏好如何。
答案 1 :(得分:1)
在很多现代语言中都有评估算术字符串表达式的方法。例如在Python中
>>> a = '1+3*3'
>>> eval(a)
10
您可以使用异常处理来捕获无效语法。
或者你可以构建算术表达式树,这里有一些例子SO: Expression Trees for Dummies.
答案 2 :(得分:1)
如上所述,我将普通字符串(中缀表示法)转换为后修复表达式。
然后,给定后修复表达式,很容易解析并评估表达式。例如,将操作数添加到堆栈中,当您找到运算符时,从堆栈中弹出值并将它们应用于操作数。如果将代码转换为修补后表达式的代码是正确的,则无需担心操作顺序或类似内容。
这种情况下的大部分工作可能都是在转换中完成的。您可以将转换后的表单存储在列表或数组中以便于访问,因此您不需要再次解析每个值。
答案 3 :(得分:0)
你说连续几个运算符无效。但想想:
5 + -2
这完全有效。
最基本的表达语法如下:
Expression = Term | Expression, AddOp, Term
Term = Factor | Term, MulOp, Factor
Factor = Number | SignOp, Factor | '(', Expression, ')'
AddOp = '+' | '-'
MulOp = '*' | '/'
SignOp = '+' | '-'
Number = Digit | Number, Digit
Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
我曾经写过一个简单的轻量级表达式解析器/求值器(数字输出中的字符串),它可以处理变量和函数。代码在Delphi中,但翻译起来应该不难。如果您有兴趣,我可以将源代码放在网上。
答案 4 :(得分:0)
另一个注意事项是,可以使用许多解析库来完成此任务。从头开始编写一个好的表达式解析器并不容易,所以我建议你查看一个库。
我在Singular Systems工作,专门研究数学成分。我们提供两个数学解析器Jep Java和Jep.Net,它们可以帮助您解决问题。祝你好运!
答案 5 :(得分:0)
对于这些受众,您希望提供的错误反馈与用于消息的程序员完全不同,例如“位置foo处的语法错误:意外'/'”。我试图在这里为教育小程序做些更好的事情:
主要思想:寻找一个不寻常的长度来找到一个最小的编辑恢复可解析性(实用,因为输入表达式不是页面长),并生成一个更长的简明英语解释解析器所坚持的内容。