编译原理---求逆波兰式方法及练习题

逆波兰表达式(Reverse Polish Notation,RPN),也称为后缀表达式,是一种将运算符放在操作数之后表示的数学表达式格式。

要求一个表达式的逆波兰式,可以按照以下步骤进行:

  1. 创建一个空的栈用于存储运算符
  2. 左到右遍历表达式的每个元素。
  3. 如果当前元素是操作数(数字),则将其输出或存储到结果中。
  4. 如果当前元素是运算符,则执行以下操作:
    • 如果栈为空,或者栈顶的元素是左括号 “(”,则将当前运算符入栈。
    • 如果当前运算符的优先级高于栈顶运算符的优先级,则将当前运算符入栈。
    • 如果当前运算符的优先级低于或等于栈顶运算符的优先级,则将栈顶运算符出栈并输出或存储到结果中,直到栈顶运算符的优先级低于当前运算符或栈为空,然后将当前运算符入栈。
    • 如果当前运算符是右括号 “)”,则连续弹出栈顶运算符并输出或存储到结果中,直到遇到左括号 “(”。注意:左括号 "("不输出或存储到结果中,只用于匹配右括号 “)”。
  5. 遍历完所有元素后,如果栈中仍然有运算符,将它们依次弹出并输出或存储到结果中
  6. 最终得到的结果即为表达式的逆波兰式。

需要注意的是,运算符的优先级决定了它们在栈中的顺序和出栈的条件。常见运算符的优先级顺序为:乘除高于加减,括号内优先计算。

在这里插入图片描述

示例一

表达式:(2 + 3) * 4 - 5

  1. 遍历到 2,直接输出或存储到结果。
  2. 遍历到 +,入栈。
  3. 遍历到 3,直接输出或存储到结果。
  4. 遍历到 ),连续弹出栈顶运算符 + 并输出或存储到结果,直到遇到 (。
  5. 遍历到 *,入栈。
  6. 遍历到 4,直接输出或存储到结果。
  7. 遍历结束,连续弹出栈中剩余的运算符 * 并输出或存储到结果。
  8. 得到的逆波兰式:2 3 + 4 * 5 -

因此,(2 + 3) * 4 - 5 的逆波兰式为 2 3 + 4 * 5 -

示例二

表达式:5 + 2 * 3 - 4 / 2

逆波兰表达式:5 2 3 * + 4 2 / -

详细步骤:

  1. 当遇到数字5时,将其添加到逆波兰表达式中:5
  2. 遇到加号+,将其压入栈中:+
  3. 遇到数字2,添加到逆波兰表达式中:5 2
  4. 遇到乘号*,由于乘号的优先级比加号高,所以将乘号压入栈中:+ *
  5. 遇到数字3,添加到逆波兰表达式中:5 2 3
  6. 遇到减号-,将减号压入栈中:+ * -
  7. 遇到数字4,添加到逆波兰表达式中:5 2 3 4
  8. 遇到除号/,此时除号的优先级高于栈顶的减号,所以将除号压入栈中:+ * - /
  9. 遇到数字2,添加到逆波兰表达式中:5 2 3 4 2
  10. 没有更多的元素需要处理,将栈中剩余的运算符依次弹出,并添加到逆波兰表达式的末尾:5 2 3 * + 4 2 / -

因此,该表达式的逆波兰表达式为 “5 2 3 * + 4 2 / -”。

示例三

表达式:(8 + 2) * (7 - 4) / 3

逆波兰表达式:8 2 + 7 4 - * 3 /

详细步骤:

  1. 将左括号压入栈中:(
  2. 遇到数字8,添加到逆波兰表达式中:8
  3. 遇到加号+,将加号压入栈中:+ (
  4. 遇到数字2,添加到逆波兰表达式中:8 2
  5. 遇到右括号),从栈中弹出元素直到遇到匹配的左括号,并将弹出的元素添加到逆波兰表达式中:8 2 +
  6. 遇到乘号*,由于乘号的优先级高于栈顶的加号,所以将乘号压入栈中:+ *
  7. 遇到左括号(,直接压入栈中:+ * (
  8. 遇到数字7,添加到逆波兰表达式中:8 2 + 7
  9. 遇到减号-,将减号压入栈中:8 2 + 7 -
  10. 遇到数字4,添加到逆波兰表达式中:8 2 + 7 - 4
  11. 遇到右括号),从栈中弹出元素直到遇到匹配的左括号,并将弹出的元素添加到逆波兰表达式中:8 2 + 7 - 4 *
  12. 遇到除号/,将除号压入栈中:8 2 + 7 - 4 * /
  13. 遇到数字3,添加到逆波兰表达式中:8 2 + 7 - 4 * / 3
  14. 没有更多的元素需要处理,将栈中剩余的运算符依次弹出,并添加到逆波兰表达式的末尾:8 2 + 7 - 4 * / 3 /

因此,该表达式的逆波兰表达式为 “8 2 + 7 4 - * 3 /”。

示例四

表达式:(5 + 4 - 2) * (7 / 3) + 8 ^ 2

逆波兰表达式:5 4 + 2 - 7 3 / * 8 2 ^ +

详细步骤:

  1. 将左括号压入栈中:(
  2. 遇到数字5,添加到逆波兰表达式中:5
  3. 遇到加号+,将加号压入栈中:+ (
  4. 遇到数字4,添加到逆波兰表达式中:5 4
  5. 遇到减号-,由于减号的优先级高于栈顶的加号,所以将减号压入栈中:5 4 + -
  6. 遇到数字2,添加到逆波兰表达式中:5 4 + 2 -
  7. 遇到右括号),从栈中弹出元素直到遇到匹配的左括号,并将弹出的元素添加到逆波兰表达式中:5 4 + 2 - 7
  8. 遇到除号/,将除号压入栈中:5 4 + 2 - 7 /
  9. 遇到数字3,添加到逆波兰表达式中:5 4 + 2 - 7 / 3
  10. 遇到乘号*,由于乘号的优先级高于栈顶的除号,所以将乘号压入栈中:5 4 + 2 - 7 / 3 *
  11. 遇到数字8,添加到逆波兰表达式中:5 4 + 2 - 7 / 3 * 8
  12. 遇到乘方符号^,将乘方符号压入栈中:5 4 + 2 - 7 / 3 * 8 ^
  13. 遇到数字2,添加到逆波兰表达式中:5 4 + 2 - 7 / 3 * 8 ^ 2
  14. 没有更多的元素需要处理,将栈中剩余的运算符依次弹出,并添加到逆波兰表达式的末尾:5 4 + 2 - 7 / 3 * 8 ^ +

因此,该表达式的逆波兰表达式为 “5 4 + 2 - 7 / 3 * 8 ^ +”。

示例五
表达式:5 + (6 - 3) * 2
逆波兰表达式:5 6 3 - 2 * +

详细遍历过程:
步骤1:遇到数字5,将其添加到逆波兰表达式中:逆波兰表达式:5
步骤2:遇到运算符"+“,由于栈为空,将其压入栈中:栈:”+"
步骤3:遇到左括号"(“,将其压入栈中:栈:”+“, “(”
步骤4:遇到数字6,将其添加到逆波兰表达式中:逆波兰表达式:5 6
步骤5:遇到运算符”-“,由于栈顶为左括号”(“,将”-“压入栈中:栈:”+“, “(”, “-”
步骤6:遇到数字3,将其添加到逆波兰表达式中:逆波兰表达式:5 6 3
步骤7:遇到右括号”)“,需要将栈中的运算符弹出并添加到逆波兰表达式中,直到遇到对应的左括号”(“。添加的运算符包括”-“: 逆波兰表达式:5 6 3 -
步骤8:遇到运算符*,由于栈为空,将其压入栈中:栈:”+", *
步骤9:遇到数字2,将其添加到逆波兰表达式中:逆波兰表达式:5 6 3 - 2
步骤10;已经遍历完所有元素,需要将栈中的运算符弹出并添加
563-2*+

  • 5
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
编译原理的输入是一个数学表达式,目的是将该表达式转换为逆波兰式m作为输出。 逆波兰式,又称为后缀表达式,是一种将操作符写在操作数之后的数学表达式。与常见的中缀表达式相比,逆波兰式更方便计算机处理和计算。 编译原理在处理输入表达式时,首先将表达式进行词法分析,将表达式中的字符序列分解为不同的单词,例如操作数或操作符。接着进行语法分析,根据语法规则将这些单词组合成语法树。 然后,编译原理使用逆波兰式转换算法将语法树转换为逆波兰式m。该算法利用栈来实现表达式的转换。遍历语法树结点的顺序是从根结点开始,先遍历左子树,再遍历右子树,最后处理根结点。 具体转换过程如下: 1. 若当前结点是操作数,则将其加入逆波兰式m中。 2. 若当前结点是操作符,则将其加入逆波兰式m中,并将当前结点入栈。 3. 若当前结点是右括号,则弹出栈中的操作符加入逆波兰式m中,直到遇到左括号为止,将左括号从栈中弹出。 4. 若当前结点是其他操作符(加减乘除等),则比较其与栈顶操作符的优先级。若当前操作符优先级较低,则将栈顶操作符出栈,并加入逆波兰式m中,然后将当前操作符入栈。若当前操作符优先级较高或相等,则直接入栈。 5. 遍历完整个语法树后,将栈中剩余的操作符出栈并加入逆波兰式m中。 最终,经过以上算法处理,逆波兰式m生成完成,作为编译原理的输出。这样,我们可以利用逆波兰式m进行数学表达式的计算。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值