我指的是它在许多计算器中的使用,比如in 35-
我的猜测(和困惑)是-
另一种可以问这个问题的方法是,后缀符号比前缀有什么优势?
有人能指点我吗?
发布于 2015-06-22 00:12:41
首先,更容易实现评估。
使用前缀时,如果您推送一个运算符,那么它的操作数,则您需要对运算符何时拥有其所有操作数具有前向知识。基本上,您需要跟踪您所推送的操作符何时有它们的所有操作数,以便您可以展开堆栈并进行计算。
由于一个复杂的表达式可能会在堆栈上有许多操作符,所以您需要有一个能够处理这个问题的数据结构。
例如,这个表达式:- + 10 20 + 30 40
将在堆栈上同时拥有一个-
和一个+
,对于每个+
,您需要知道是否有可用的操作数。
使用后缀时,当您推送运算符时,操作数(应该)已经在堆栈上了,只需弹出操作数并进行计算。您只需要一个可以处理操作数的堆栈,而不需要其他数据结构。
发布于 2015-06-22 00:56:13
基本上,因为如果您在后缀中编写表达式,则可以只使用堆栈计算该表达式。
示例
expression = 1 2 + 3 4 + *
stack = [ ]
Read 1, 1 is Operand, Push 1
[ 1 ]
Read 2, 2 is Operand, Push 2
[ 1 2 ]
Read +, + is Operation, Pop two Operands 1 2
Evaluate 1 + 2 = 3, Push 3
[ 3 ]
Read 3, 3 is Operand, Push 3
[ 3 3 ]
Read 4, 4 is Operand, Push 4
[ 3 3 4 ]
Read +, + is Operation, Pop two Operands 3 4
Evaluate 3 + 4 = 7, Push 7
[ 3 7 ]
Read *, * is Operation, Pop two Operands 3 7
Evaluate 3 * 7 = 21, Push 21
[ 21 ]
发布于 2015-06-23 08:40:04
前缀符号可能更常用..。在数学中,用像F(x,y)这样的表达式。这是一个非常古老的惯例,但就像许多旧的系统(英尺和英寸,信纸)相比,它有缺点,我们可以做什么,如果我们使用一个更深思熟虑的设计系统。
几乎每一年,大学数学教科书都要浪费一页,至少要解释一下,f(g(x))
意味着我们首先应用g
,然后是f
。按照阅读顺序这样做更有意义:x.f.g
意味着我们首先应用f
。如果我们想在“h
”之后应用x.f.g.h
,我们只需要说“x.f.g.h
”。
举个例子,考虑我最近不得不处理的3d旋转中的一个问题。我们希望按照XYZ惯例旋转一个向量。在后缀中,操作是vec.rotx(phi).roty(theta).rotz(psi)
。使用前缀,我们必须重载*
或()
,然后反转操作的顺序,例如rotz*roty*rotx*vec
。当你想要思考更大的问题时,必须一直考虑这个问题,这是很容易出错的,而且令人恼火。
例如,我在其他人的代码中看到了类似rotx*roty*rotz*vec
的东西,我不知道这是错误还是不寻常的ZYX旋转约定。我还是不知道。程序工作正常,因此它在内部是一致的,但在这种情况下,前缀表示法很难维护。
前缀表示法的另一个问题是,当我们(或一台计算机)解析表达式f(g(h(x)))
时,我们必须将f
保存在内存中(或堆栈上),然后是g
,然后是h
,然后ok,我们可以将h
应用于x
,然后将g
应用于结果,然后将f
应用于结果。与x.f.g.h
相比,内存中的内容太多了。在某一时刻(对人类来说,比计算机快得多),我们将耗尽记忆。以这种方式失败并不常见,但是为什么在x.f.g.h
不需要短期内存的情况下甚至打开了这扇门。这就像递归和循环的区别。
还有一件事:f(g(h(x)))
有太多的括号,开始看起来像Lisp。当涉及运算符优先级时,后缀表示法是明确的。
一些数学家(尤其是内森·雅各布森)试图改变惯例,因为在非交换代数中,如果顺序很重要,后缀就容易得多,但没有什么用处。但既然我们有机会做更多的事情,更好的,在计算,我们应该抓住这个机会。
https://stackoverflow.com/questions/30974889
复制相似问题