中缀表达式转后缀表达式

476 阅读3分钟

中缀表达式

a + b * c + (d * e + f) * g

后缀表达式(逆波兰表达式)

对应上面: abc * + de * f + g * +

中缀转后缀

算法思想

  • 循环遍历每一个字符
    • 非运算符(数字)直接输出
    • 运算符做以下处理
      • 若栈为空,将运算符压入栈中
      • 若栈不为空
        • 遇到普通运算符{+ - * /},若栈顶元素优先级>=即将入栈的运算符(还未入栈)且栈不为空,弹出并输出栈顶元素,直到条件不满足,则将未入栈的运算符压入栈中
        • 遇到左括号(,直接压入栈中压入之后,除非遇到右括号),否则不弹出
        • 遇到右括号),弹出并输出栈顶元素,直到遇到栈中的左括号(左括号只弹出不输出
  • 循环结束后,将栈中的元素全部弹出并输出即可

例子解析

输入a + b * c + (d * e + f) * g

  • 循环开始
  • 遇到a直接输出
  • 遇到加号+,压入栈中
  • 遇到b直接输出
  • 遇到乘号*,栈顶元素(即+)优先级 < *,不弹出+,将*压入栈中
  • 遇到c直接输出
  • 遇到加号+,栈顶元素(即*)优先级 > +,弹出并输出*,此时栈顶元素变成+,由于+优先级 == +,弹出并输出+,栈变为空,将未入栈的+压入栈中
  • 遇到左括号(,直接压入栈中
  • 遇到d直接输出
  • 遇到乘号*,栈顶元素(即+)优先级 < *,不弹出+,将*压入栈中
  • 遇到e直接输出
  • 遇到加号+,栈顶元素(即*)优先级 > +,弹出并输出*,此时栈顶元素变为(,由于还未遇到右括号),暂时不弹出(
  • 遇到加号+,因为栈顶元素是(,此时直接将+压入栈中即可
  • 遇到f直接输出
  • 遇到右括号),弹出并输出栈顶元素+,继续弹出栈顶元素(,因为是左括号,只弹出不输出
  • 遇到乘号*,栈顶元素(即+)优先级 < *,不弹出+,将*压入栈中
  • 遇到g直接输出
  • 循环结束
  • 弹出并输出栈中所有元素(此时栈中有* +

此时顺利得到后缀表达式abc * + de * f + g * +

后缀表达式运算

算法思想

  • 循环遍历后缀表达式
    • 运算符直接输出
    • 非运算符(数字)
      • 未遇到运算符,直接压入栈中
      • 遇到运算符,弹出栈中两个元素(即栈顶元素和紧挨着的元素),根据此时遇到的运算符进行相关运算,然后将结果压入栈中
  • 循环结束,弹出并输出栈顶元素,此栈顶元素即为运算结果

例子解析

输入abc * + de * f + g * +

  • 循环开始
  • 遇到a,压入栈中
  • 遇到b,压入栈中
  • 遇到c,压入栈中
  • 遇到乘号*,弹出bc进行*操作,将运算结果b*c压入栈中
  • 遇到加号+,弹出b*c和a进行+操作,将运算结果(b*c)+a压入栈中
  • 遇到d,压入栈中
  • 遇到e,压入栈中
  • 遇到乘号*,弹出ed进行*操作,将运算结果e*d压入栈中
  • 遇到f,压入栈中
  • 遇到加号+,弹出fe*d进行+操作,将运算结果e*d+f压入栈中
  • 遇到g,压入栈中
  • 遇到乘号*,弹出ge*d+f进行*操作,将运算结果(e*d+f)*g压入栈中
  • 遇到加号+,弹出果(e*d+f)*g(b*c)+a进行+操作,将运算结果((b*c)+a)+((e*d+f)*g)压入栈中
  • 循环结束
  • 弹出栈顶元素((b*c)+a)+((e*d+f)*g),即为运算结果