了解中序表达式的表示法与计算方法 (转)

[php] 了解中序表达式的表示法与计算方法
 

中序表达式的表示法与计算方法

这些东西在算法的书中都有讲到,以下是根据回忆做出的记录。

通常编程中的表达式计算均是从左往右读取,考虑运算符优先级,这些都是中序表达式。
(相比较于前序和后序主要是指操作符放在前面或后面,所以中序指操作符放在中间)

处理这种表达式时一般需要 2个栈来存放运算符和操作数,如果运算符的优先权高于下
一个操作符时,则从堆栈中取出操作数与该运算符进行计算成本。

下面请看一个简单例子:(呆会针对常见迷惑的PHP表达式计算作出理解)

$i + $x / $y - $j

   0) 建立2个栈,操作数栈和运算符的栈,都是空的。

   从左往右读取表达式,如果读到操作数就放入操作数栈中,运算符则放入运算符的栈中

   1) 读到 $i

   +-------+
   |  $i   |
 --+-------+--    --+-------+--
   操作数栈         操作符栈

   2) 读到 +

   +-------+        +-------+
   |  $i   |        |   +   |
 --+-------+--    --+-------+--
   操作数栈         操作符栈

   3) 读到 $x

   +-------+
   |  $x   |
   +-------+        +-------+
   |  $i   |        |   +   |
 --+-------+--    --+-------+--
   操作数栈         操作符栈


   3) 读到 / 由于 / 的优先级比栈中的 + 高, 则将 / 直接存入栈中

   +-------+        +-------+
   |  $x   |        |   /   |
   +-------+        +-------+
   |  $i   |        |   +   |
 --+-------+--    --+-------+--
   操作数栈         操作符栈 

  4) 读到 $y

   +-------+
   |  $y   |
   +-------+        +-------+
   |  $x   |        |   /   |
   +-------+        +-------+
   |  $i   |        |   +   |
 --+-------+--    --+-------+--
   操作数栈         操作符栈 

  5) 接着读到 -,由于 - 的运算符比 / 低,故取出 / 并从操作数栈中取出相应的操作数进行
     计算,由于 / 是双目运算,故取出 $y, $x 进行 / 运算,然后将 - 存符符号栈,并接着
     读取到 $j

   +-------+
   |  $j   |
   +-------+        +-------+
   | $x/$y |        |   -   |
   +-------+        +-------+
   |  $i   |        |   +   |
 --+-------+--    --+-------+--
   操作数栈         操作符栈 

  6) 由于操作符栈中还有未运算的符号,故每取出一个运算符同时从操作数栈中取出相应的数进
     行运算,直到操作符栈为空。完成表达式计算时,操作数栈中的内容即为表达式的结果。懒
     得再画图了,麻烦

  6.1) 取出 -,双目运算 $x/$y - $j
  6.2) 取出 +,双目运算 $i + $x/$y - $j
__________________________________________________________________________________

再回到 PHP中来,我们看两个例子,之前在 geel 及我发的 Quiz 中的例子, :p

1)  $i = 2; echo ($i++ + $i);

1.1) 根据上面的基础知识得到以下栈图

  +------+        +------+
  |  $i  |        |  ++  |
--+------+--    --+------+--

1.2) 接着读取到 + 号,发现 + 号的优先级比 ++ 低,故先运算 ++ 再将 + 压入栈(单目运算)

  +----------------------------+        +------+
  | $i++(注:栈值=2,$i=3)       |        |  +   |
--+----------------------------+--    --+------+--

1.3) 读取到 $i 压入操作数栈  ($i = 3)

  +----------+
  |  $i (=3) |
  +----------+        +------+
  |  2       |        |  +   |
--+----------+--    --+------+--

1.2) 取出 + 作最后运算,至此,操作符栈已经全部完成,故运算完毕,操作数中的值就是结果
  即 5.

  +----------+
  |  3 + 2   |
--+----------+--    --+------+--

2)  $a = 1; $b =&$a; $b = $a++;

2.1) 仅从 ($b = $a++)出发,先得出如下栈图

  +------+        +------+
  |  $b  |        |  =   |
--+------+--    --+------+--

2.2) 接着读取到操作数 $a

  +------+
  |  $a  |
  +------+        +------+
  |  $b  |        |  =   |
--+------+--    --+------+--

2.3) 读到到操作符 ++ ,由于 ++ 的优先级比 = 高,故先取出 $a 做 ++ 运算

  +----------------------+
  |  $a++ (栈值:1,$a=2)  |
  +----------------------+        +------+
  |  $b                  |        |  =   |
--+----------------------+--    --+------+--

2.4) 读取 = 号作最后运算

  +-----------+        +------+
  |  $b = 1   |        |  =   |
--+-----------+--    --+------+--

2.5) 由于 $b 和 $a 互为关联,$a, $b的值均为最后一次赋值($b=1)的值,所以 $a = $b = 1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值