逆波兰表达式
(Reverse Polish Notation,RPN),也称为后缀表达式
,是一种将运算符放在操作数之后表示的数学表达式格式。
要求一个表达式的逆波兰式,可以按照以下步骤
进行:
- 创建一个空的栈用于
存储运算符
。 - 从
左到右
遍历表达式的每个元素。 - 如果当前元素是操作数(
数字
),则将其输出或存储到结果中。 - 如果当前元素是
运算符
,则执行以下操作:- 如果栈为空,或者栈顶的元素是左括号 “(”,则将当前运算符入栈。
- 如果当前运算符的优先级
高于
栈顶运算符的优先级,则将当前运算符入栈。 - 如果当前运算符的优先级
低于或等于
栈顶运算符的优先级,则将栈顶运算符出栈并输出或存储到结果中
,直到栈顶运算符的优先级低于当前运算符或栈为空,然后将当前运算符入栈。 - 如果当前运算符是右括号 “)”,则连续弹出栈顶运算符并输出或存储到结果中,直到遇到左括号 “(”。注意:左括号 "("
不输出或存储到结果中
,只用于匹配右括号 “)”。
- 遍历完所有元素后,如果栈中仍然有运算符,将它们
依次弹出并输出或存储到结果中
。 - 最终得到的结果即为表达式的逆波兰式。
需要注意的是,运算符的优先级决定了它们在栈中的顺序和出栈的条件。常见运算符的优先级顺序为:乘除高于加减,括号内优先计算。
示例一
:
表达式:(2 + 3) * 4 - 5
- 遍历到 2,直接输出或存储到结果。
- 遍历到 +,入栈。
- 遍历到 3,直接输出或存储到结果。
- 遍历到 ),连续弹出栈顶运算符 + 并输出或存储到结果,直到遇到 (。
- 遍历到 *,入栈。
- 遍历到 4,直接输出或存储到结果。
- 遍历结束,连续弹出栈中剩余的运算符 * 并输出或存储到结果。
- 得到的逆波兰式:2 3 + 4 * 5 -
因此,(2 + 3) * 4 - 5 的逆波兰式为 2 3 + 4 * 5 -
示例二
:
表达式:5 + 2 * 3 - 4 / 2
逆波兰表达式:5 2 3 * + 4 2 / -
详细步骤:
- 当遇到数字5时,将其添加到逆波兰表达式中:5
- 遇到加号+,将其压入栈中:+
- 遇到数字2,添加到逆波兰表达式中:5 2
- 遇到乘号*,由于乘号的优先级比加号高,所以将乘号压入栈中:+ *
- 遇到数字3,添加到逆波兰表达式中:5 2 3
- 遇到减号-,将减号压入栈中:+ * -
- 遇到数字4,添加到逆波兰表达式中:5 2 3 4
- 遇到除号/,此时除号的优先级高于栈顶的减号,所以将除号压入栈中:+ * - /
- 遇到数字2,添加到逆波兰表达式中:5 2 3 4 2
- 没有更多的元素需要处理,将栈中剩余的运算符依次弹出,并添加到逆波兰表达式的末尾:5 2 3 * + 4 2 / -
因此,该表达式的逆波兰表达式为 “5 2 3 * + 4 2 / -”。
示例三
:
表达式:(8 + 2) * (7 - 4) / 3
逆波兰表达式:8 2 + 7 4 - * 3 /
详细步骤:
- 将左括号压入栈中:(
- 遇到数字8,添加到逆波兰表达式中:8
- 遇到加号+,将加号压入栈中:+ (
- 遇到数字2,添加到逆波兰表达式中:8 2
- 遇到右括号),从栈中弹出元素直到遇到匹配的左括号,并将弹出的元素添加到逆波兰表达式中:8 2 +
- 遇到乘号*,由于乘号的优先级高于栈顶的加号,所以将乘号压入栈中:+ *
- 遇到左括号(,直接压入栈中:+ * (
- 遇到数字7,添加到逆波兰表达式中:8 2 + 7
- 遇到减号-,将减号压入栈中:8 2 + 7 -
- 遇到数字4,添加到逆波兰表达式中:8 2 + 7 - 4
- 遇到右括号),从栈中弹出元素直到遇到匹配的左括号,并将弹出的元素添加到逆波兰表达式中:8 2 + 7 - 4 *
- 遇到除号/,将除号压入栈中:8 2 + 7 - 4 * /
- 遇到数字3,添加到逆波兰表达式中:8 2 + 7 - 4 * / 3
- 没有更多的元素需要处理,将栈中剩余的运算符依次弹出,并添加到逆波兰表达式的末尾:8 2 + 7 - 4 * / 3 /
因此,该表达式的逆波兰表达式为 “8 2 + 7 4 - * 3 /”。
示例四
:
表达式:(5 + 4 - 2) * (7 / 3) + 8 ^ 2
逆波兰表达式:5 4 + 2 - 7 3 / * 8 2 ^ +
详细步骤:
- 将左括号压入栈中:(
- 遇到数字5,添加到逆波兰表达式中:5
- 遇到加号+,将加号压入栈中:+ (
- 遇到数字4,添加到逆波兰表达式中:5 4
- 遇到减号-,由于减号的优先级高于栈顶的加号,所以将减号压入栈中:5 4 + -
- 遇到数字2,添加到逆波兰表达式中:5 4 + 2 -
- 遇到右括号),从栈中弹出元素直到遇到匹配的左括号,并将弹出的元素添加到逆波兰表达式中:5 4 + 2 - 7
- 遇到除号/,将除号压入栈中:5 4 + 2 - 7 /
- 遇到数字3,添加到逆波兰表达式中:5 4 + 2 - 7 / 3
- 遇到乘号*,由于乘号的优先级高于栈顶的除号,所以将乘号压入栈中:5 4 + 2 - 7 / 3 *
- 遇到数字8,添加到逆波兰表达式中:5 4 + 2 - 7 / 3 * 8
- 遇到乘方符号^,将乘方符号压入栈中:5 4 + 2 - 7 / 3 * 8 ^
- 遇到数字2,添加到逆波兰表达式中:5 4 + 2 - 7 / 3 * 8 ^ 2
- 没有更多的元素需要处理,将栈中剩余的运算符依次弹出,并添加到逆波兰表达式的末尾: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*+