在 C 中计算后缀表达式时,如果我们的标记是一个运算符,我们必须将其放入堆栈中,使其具有最高优先级。
我的问题是运算符*
, /
, %
, 具有最高优先级。
我们是否也需要考虑关联性?由于所有这些运算符都具有 LEFT-TO-RIGHT关联性,是否会/
获得更高的偏好*
?
在 C 中计算后缀表达式时,如果我们的标记是一个运算符,我们必须将其放入堆栈中,使其具有最高优先级。
我的问题是运算符*
, /
, %
, 具有最高优先级。
我们是否也需要考虑关联性?由于所有这些运算符都具有 LEFT-TO-RIGHT关联性,是否会/
获得更高的偏好*
?
优先级通常只适用于中缀符号。后缀(和前缀)符号通常被认为是明确指定哪些操作数与哪个运算符相关联。只有在解析中存在歧义时,优先级才会发挥作用,而在后缀表示法中则不然。
中缀表达式中出现的优先级问题
4 * 5 + 3 / 12
转换为 RPN 表单后根本不存在
4 5 * 3 + 12 /
或前缀形式
(/ (+ (* 4 5) 3) 12)
.
在考虑诸如Shunting-Yard 算法之类的东西时,可能会产生混淆,该算法可用于从或直接评估中缀表达式生成 RPN 表示。它通过将运算符延迟到辅助堆栈上来处理运算符优先级,直到较低优先级的运算符强制它被弹出和评估(或输出)。
运算符 *
, /
, 的优先级%
相同,并且关联性是从左到右的。所以像这样的表达式:
a * b / c /* both operators have same precedence */
等同于:
(a * b) / c
类似的表达式如下:
a / b * c /* both operators have same precedence */
等同于:
( a / b ) * c
因此,即使运算符的优先级相同,但假设它们出现在表达式中(不带括号),那么由于从左到右的关联性,最左边的运算符具有更高的优先级。
注意从概念上讲,我们在表达式中使用括号来覆盖运算符的优先级,因此虽然 expression: a / b * c
与: 相同,(a / b) * c
但我们可以通过将 expression 写为 来强制*
首先使用。如果您在编写代码时对运算符优先级有混淆,我的意思是使用括号。(
)
a / ( b * c)
编辑:
在 POSTFIX 和 PREFIX 形式中不要使用括号(
)
。运算符的优先级是按照表达式中出现的顺序决定的,因此在评估表达式时,它不需要搜索下一个操作来执行 - 因此评估变得很快。
而在 INFIX 表达式中,运算符的优先级可以被括号覆盖(
)
。因此,中缀表达式中有括号——它需要搜索接下来要执行的操作,例如 a + b % d——并且表达式的评估很慢。
这就是转换在计算机科学中有用的原因。
因此编译器首先将中缀表达式转换为等效的后缀形式(使用语法规则),然后生成目标代码来评估表达式值。这就是我们研究后缀和前缀形式的原因。
并且根据优先级和关联性规则,以下表达式:
a * b / c /* both operators have same precedence */
将被翻译成:
a b * c /
和表达
a / b * c /* both operators have same precedence */
将被翻译成
a b / c *
我的问题是运算符
*
,/
,%
, 具有最高优先级。
它们是相等的,就像+
和-
(binary) 相等一样。
我们是否也需要考虑关联性?
是的,例如1 + 2 + 3
需要变成(1 + 2) + 3
,即1, 2, ADD, 3, ADD,
相对于1, 2, 3, ADD, ADD.
由于所有这些运算符都具有从左到右的关联性,因此 / 会获得比 * 更高的偏好吗?
关联性与优先级没有任何关系。这个问题没有意义。
但是如果你只是计算一个现有的 RPN 表达式,正如你的标题所说,我不知道你为什么要问这个。您只需推送操作数并在操作符出现时对其进行评估。你真的在问翻译成RPN 吗?