给定任何字符串表达式,如何填充树?
我有一个我被困住的作业。
我需要使用任何数据结构来评估以下表达式(( 5 * 10 ) /2 - (( 2 + 3) + 6))
。
使用堆栈,我能够验证字符串是否格式良好。但是,如何将各种值添加到树中,然后按顺序对其进行评估。
请告诉我有关如何阅读字符串((( 490 * 9 ) / 2)/5/6 - (( 2/4 + 3) + 6 * 5))
例如,当输入表达式中的第15个子字符串时,如何让(-
)成为三者的根?如何确保(/
)6表达式发生在(/
)5等之后。
答案 0 :(得分:3)
此处提供了您要找的内容:http://www.codeproject.com/Articles/88435/Simple-Guide-to-Mathematical-Expression-Parsing
答案 1 :(得分:2)
评估任何字符串[代表数学]表达式
你需要做三件事:
你可以很容易地做到这一点。
我会使用Haskell表示法,因为它很简洁,但如果你愿意,你可以翻译它。
您的语言类型:
data Exp = Op BinOp Exp Exp
| Lit Int
data BinOp = Plus
| Times
| Div
| Sub
现在,我们可以用这种语言为表达式编写一个解释器:
eval :: Exp -> Int
eval (Lit n) = n
eval (Op o e1 e2) =
let v1 = eval e1
v2 = eval e2
in case o of
Plus -> v1 + v2
Times -> v1 * v2
Sub -> v1 - v2
Div -> v1 / v2 -- note, may fail!
确定。这就是您所用语言的评估者。现在写一个递归下降解析器......
答案 2 :(得分:1)
括号表示操作顺序,类似于您使用堆栈确保匹配的所有内容,您可以解析这些匹配并将它们用作树中的元素,以创建用于评估的层次结构,其中运算符是每个广度级的括号匹配。
答案 3 :(得分:1)
编辑第二个:操作澄清,参见其他答案
答案 4 :(得分:1)
此处的其他答案包括将表达式树读入内存,但它们不包括在构建树后对树进行评估。
评估树的一般策略是树应该由节点和叶子组成,其中节点是具有子节点的运算符,而叶子是常量值。例如,表达式(((490 * 9)/ 2)/ 5/6 - ((2/4 + 3)+ 6 * 5))转换为树
- / \ / \ div + / \ / \ div 6 + * / \ / \ / \ div 5 div 3 6 5 / \ / \ * 2 2 4 / \ 450 9
要评估此树,请从根目录开始。首先递归计算左子树和右子树,然后将运算符应用于两个子树计算的结果。每个叶子(数字)都评估自己。
在这种情况下,您将从根( - )开始,将左子树评估为73.5,将右子树评估为33.5,然后减去最终结果为40。
作为一个更精确的例子,让我们看看树的最左边的节点,在进行了几层递归调用之后。叶450的计算结果为450,叶9的计算结果为9,并且节点(* 450 9)
(以类似Lisp的前缀表示法编写树的节点)的计算结果为4050.因此,从节点(/ (* 450 9) 2)
开始,左递归调用求值为4050,右递归调用求值为2,表示整个节点求值为2025.只要在组合值之前从节点进行递归调用,并确保每个叶子对其自身求值,树评估很简单。