前缀、中缀、后缀之间的转换

1、概念理解: 对表达式的记法常见的有三种,即熟知的中缀记法,还有计算机所读取的前缀(波兰PN)记法后缀(逆波兰RPN)记法。三者之间区分依据是运算符相对于操作数的位置——前缀表达式的运算符位于与其相关的操作数之前,中缀表达式则是运算符位于操作数之间,而后缀表达式则是运算符位于操作数之后。PS:前(后)缀记法都是不需要括号的

2.1 后缀表达式的计算结果:

  规则:左到右遍历表达式的每一个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进行运算(次顶数字 option 栈顶数字),运算结果进栈,一直到获得最终结果。

   例子:9 3 1- 3 *+10 2/+

  (1) 从左至右扫描,将9 3 1按顺序压入堆栈;
  (2) 遇到 - 运算符,因此弹出1和3(1为栈顶元素,3为次顶元素),计算出3-1的值,得2,再将2入栈;
  (3) 将3入栈;
  (4) 接下来是 * 运算符,因此弹出3和2,计算出2×3=6,将6入栈;
  (5) 遇到 + 运算符,因此弹出6和9,计算出9+6的值,得15,再将15入栈;
  (6) 将10,2入栈;
  (7) 接下来是 / 运算符,因此弹出2和10,计算出10/2=5,将5入栈;
  (8) 最后是 + 运算符,计算出15+5的值,即20,出栈,由此得出最终结果。

2.2中缀表达式转为后缀表达式

   规则:左到右遍历中缀表达式的每一个数字和符号,若是数字就输出,即为后缀表达式中的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于栈顶符号则栈顶元素(符号)依次出栈并输出并将当前符号进栈(ps:若当前符号优先级与栈顶相同则弹出栈顶元素并输出),一直到最终输出后缀表达式为止。

遵循以下步骤:
(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;
(2) 从左至右扫描中缀表达式;
(3) 遇到操作数时,将其压入S2;
(4) 遇到运算符时,比较其与S1栈顶运算符的优先级:
(4-1) 如果S1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
(4-2) 否则,若优先级比栈顶运算符的高,也将运算符压入S1(注意转换为前缀表达式时是优先级较高或相同,而这里则不包括相同的情况);
(4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;
(5) 遇到括号时:
(5-1) 如果是左括号“(”,则直接压入S1;
(5-2) 如果是右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到左括号为止,此时将这一对括号丢弃;
(6) 重复步骤(2)至(5),直到表达式的最右边;
(7) 将S1中剩余的运算符依次弹出并压入S2;
(8) 依次弹出S2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式(转换为前缀表达式时不用逆序)。

   例子:9+(3-1)*3+10/2

      (1) 从左至右扫描,将9输出,+ (入栈;  输出:9
  (2) 遇到3输出,( - 入栈 ,1输出; 输出:9 3 1

  (3) 遇到运算符),因此 - 出栈并输出; 输出:9 3 1 -
  (4) 接下来是 * 运算符入栈,优先级高于 + ,因此不输出; 输出:9 3 1 -
  (5) 3输出,遇到 + ,优先级低于 * ,所以* 输出;  输出:9 3 1- 3*

     (6)没有比+ 更低优先级,所以全部出栈,并将当前符号“+” 进栈; 输出:9 3 1 -3 * +
  (6) 将10输出,/  入栈 ,优先级高于 + 不输出; 输出 :9 3 1 - 3* +10
  (7) 接下来是2输出,没有其他运算符入栈,所有运算符出栈并输出; 输出: 9 3 1 - 3*+10 2 /+

  综上:让计算机出来通常标准的中缀表达式,最重要的两步:

      1) 将中缀表达式转为后缀表达式(栈用来进出运算的符号

      2)将后缀表达式进行运算得出结果(栈用来进出运算的数字)

3.1 前缀表达式的计算机求值:
    规则:右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 option 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。

    例如:前缀表达式“- × + 3 4 5 6”:


  (1) 从右至左扫描,将6、5、4、3压入堆栈;
  (2) 遇到+运算符,弹出3和4(3为栈顶元素,4为次顶元素,注意与后缀表达式做比较),计算出3+4的值,得7,再将7入栈;
  (3) 接下来是×运算符,因此弹出7和5,计算出7×5=35,将35入栈;
  (4) 最后是-运算符,计算出35-6的值,即29,由此得出最终结果。

3.2 将中缀表达式转换为前缀表达式:
遵循以下步骤:
(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;
(2) 从右至左扫描中缀表达式;
(3) 遇到操作数时,将其压入S2;
(4) 遇到运算符时,比较其与S1栈顶运算符的优先级:
(4-1) 如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符入栈;
(4-2) 否则,若优先级比栈顶运算符的较高或相等,也将运算符压入S1;
(4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;
(5) 遇到括号时:
(5-1) 如果是右括号“)”,则直接压入S1;
(5-2) 如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号丢弃;
(6) 重复步骤(2)至(5),直到表达式的最左边;
(7) 将S1中剩余的运算符依次弹出并压入S2;
(8) 依次弹出S2中的元素并输出,结果即为中缀表达式对应的前缀表达式。

posted @ 2017-07-10 15:02  心随所享  阅读(2991)  评论(0编辑  收藏  举报