非通勤运算符的中缀到后缀
infix to postfix with non-commuting operators
我对后缀与中缀中的 - / 运算符有疑问。
来自作业
The input string 5 4 + 3 10 * + is equivalent to the infix expression
(5 + 4) + (3 * 10) The answer is 39.
我照着做。然后我对这个说法感到困惑。
We also have to worry about the non-commuting operators – and / . We
will evaluate the postfix string 4 5 – as 4 – 5 and,
likewise, will evaluate 4 5 / as 4 / 5 .
然而,当我这样做时......我得到了中缀和后缀的不同结果。
修改第一个示例以包含减法。
中缀
(5 - 4) + (3 * 10) = 31
后缀
5 4 - 3 10 * +
29....对吧?
所以我很困惑。中缀和后缀的结果应该是一样的吧?这是实际作业中的错字还是我做错了什么?
后缀的计算结果也为 31。
让我们一步步过一遍:我们的表达式是
5 4 - 3 10 * +
所以堆栈的进展如下:
5
5 4
1 # after evaluating -, i.e. popping 5 and 4 and pushing 5 - 4
1 3
1 3 10
1 30 # after evaluating *, i.e. popping 3 and 10 and pushing 3 * 10
31 # after evaluating +, i.e. popping 1 and 30 and pushing 1 + 30
在-和/的语句中,是4 5 -。那是-1,即4-5。
在较长的表达式中:5 4 - 3 10 * +
是 5 - 4,因为 5 在前。因此,它是 (5-4) + (3*10) = 31。
如果是 4 5 - 3 10 * + 那么计算结果将是 29(即 (4-5) + (3*10))。这与前缀或后缀表示法无关,而是我们评估参数的顺序,因为 - 和 / 是不可交换的。赋值指定它们将按 "intuitive" 顺序进行评估,即 x y - 表示 x - y。
我认为您可能感到困惑,因为示例是 4-5 而您的示例是中缀表示法的 5-4。
求后缀5 4 - 3 10 * +:
5 4 - = 5 - 4 = 1
3 10 * = 3 * 10 = 30
1 30 + = 1 + 30 = 31
你作业中的第二个陈述只是澄清了如果你有类似 4 5 - 的东西,它将是 4 - 5 而不是 5 - 4。
当你评估后缀时,你使用一个堆栈:你压入操作数,当你到达一个运算符时,你弹出所需的操作数并压入评估结果。
对于像 +
这样的交换运算符,操作数的顺序并不重要。例如:
5 4 +
可以评价为
PUSH 5
PUSH 4
PUSH (POP + POP)
第一个 POP 将产生 4,第二个 POP 将产生 5。所以你真的评估了 4+5。
但在非交换运算符的情况下,这将不起作用。您必须评估 5 / 4,而不是 4 / 5。因此您需要使用临时变量:
PUSH 5
PUSH 4
let d = POP; // divisor = 4
let q = POP; // quotient = 5
PUSH q/d; // push the dividend
或者引入一个 SWAP 操作,交换栈顶的两项:
PUSH 5
PUSH 4
SWAP
PUSH (POP / POP)
否则编译后缀以便以相反的顺序推送:
PUSH 4
PUSH 5
PUSH (POP/POP)
我对后缀与中缀中的 - / 运算符有疑问。
来自作业
The input string 5 4 + 3 10 * + is equivalent to the infix expression (5 + 4) + (3 * 10) The answer is 39.
我照着做。然后我对这个说法感到困惑。
We also have to worry about the non-commuting operators – and / . We will evaluate the postfix string 4 5 – as 4 – 5 and, likewise, will evaluate 4 5 / as 4 / 5 .
然而,当我这样做时......我得到了中缀和后缀的不同结果。
修改第一个示例以包含减法。
中缀
(5 - 4) + (3 * 10) = 31
后缀
5 4 - 3 10 * +
29....对吧?
所以我很困惑。中缀和后缀的结果应该是一样的吧?这是实际作业中的错字还是我做错了什么?
后缀的计算结果也为 31。
让我们一步步过一遍:我们的表达式是
5 4 - 3 10 * +
所以堆栈的进展如下:
5
5 4
1 # after evaluating -, i.e. popping 5 and 4 and pushing 5 - 4
1 3
1 3 10
1 30 # after evaluating *, i.e. popping 3 and 10 and pushing 3 * 10
31 # after evaluating +, i.e. popping 1 and 30 and pushing 1 + 30
在-和/的语句中,是4 5 -。那是-1,即4-5。
在较长的表达式中:5 4 - 3 10 * +
是 5 - 4,因为 5 在前。因此,它是 (5-4) + (3*10) = 31。
如果是 4 5 - 3 10 * + 那么计算结果将是 29(即 (4-5) + (3*10))。这与前缀或后缀表示法无关,而是我们评估参数的顺序,因为 - 和 / 是不可交换的。赋值指定它们将按 "intuitive" 顺序进行评估,即 x y - 表示 x - y。
我认为您可能感到困惑,因为示例是 4-5 而您的示例是中缀表示法的 5-4。
求后缀5 4 - 3 10 * +:
5 4 - = 5 - 4 = 1
3 10 * = 3 * 10 = 30
1 30 + = 1 + 30 = 31
你作业中的第二个陈述只是澄清了如果你有类似 4 5 - 的东西,它将是 4 - 5 而不是 5 - 4。
当你评估后缀时,你使用一个堆栈:你压入操作数,当你到达一个运算符时,你弹出所需的操作数并压入评估结果。
对于像 +
这样的交换运算符,操作数的顺序并不重要。例如:
5 4 +
可以评价为
PUSH 5
PUSH 4
PUSH (POP + POP)
第一个 POP 将产生 4,第二个 POP 将产生 5。所以你真的评估了 4+5。
但在非交换运算符的情况下,这将不起作用。您必须评估 5 / 4,而不是 4 / 5。因此您需要使用临时变量:
PUSH 5
PUSH 4
let d = POP; // divisor = 4
let q = POP; // quotient = 5
PUSH q/d; // push the dividend
或者引入一个 SWAP 操作,交换栈顶的两项:
PUSH 5
PUSH 4
SWAP
PUSH (POP / POP)
否则编译后缀以便以相反的顺序推送:
PUSH 4
PUSH 5
PUSH (POP/POP)