算术表达式是最常用的表达式,又称为数值表达式。它是通过算术运算符来进行运算的数学公式。
表达式计算 (expression evaluation) 是程序设计语言编译中的一个最基本问题,也是早期计算机语言研究的一项重要成果,它使得高级语言程序员可以使用与数学形式相一致的方式书写表达式。
一般我们接触比较熟悉的是 中缀表达式 。
中缀表达式是常见的运算表达式,如 ( 3 4 ) × 5 - 6 。中缀表达式在我们日常生活中应用最为广泛,也最符合人的计算思维。
今天来科普一下比较不常用的前缀表达式。
前缀表达式
前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前。LeetCode 第 150 号问题就用到了波兰式的概念,具体可以点击了解一下。
例如:中缀表达式 ( 2 3 ) × 4 - 5,采用前缀表达式为:- × 2 3 4 5
前缀表达式运算:
•对前缀表达式进行从右至左依次扫描•当遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 op 次顶元素),并将结果入栈•重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果
例如前缀表达式 : - × 2 3 4 5
•从右至左扫描,将5、4、3、2压入堆栈•遇到 运算符,因此弹出 2 和 3( 2 为栈顶元素,3 为次顶元素,注意与后缀表达式做比较),计算出 2 3 的值,得 5,再将 5 入栈;•接下来是 × 运算符,因此弹出 5 和 4 ,计算出 5 × 4 = 20,将 20 入栈•最后是 - 运算符,计算出 20 - 5 的值,即 15,由此得出最终计算结果
中缀表达式转为前缀表达式: 转换步骤如下:
•(1)初始化两个栈:运算符栈 s1,储存中间结果的栈 s2•(2)从右至左扫描中缀表达式•(3)遇到操作数时,将其压入 s2•(4)遇到运算符时,比较其与 s1 栈顶运算符的优先级
•a:如果 s1 为空,或栈顶运算符为右括号 “ ) ”,则直接将此运算符入栈 •b:否则,若优先级比栈顶运算符的较高或相等,也将运算符压入 s1 •c:否则,将 s1 栈顶的运算符弹出并压入到 s2 中,再次转到 ( 4 - 1 ) 与 s1 中新的栈顶运算符相比
•(5)遇到括号时
•a:如果是右括号“)”,则直接压入 s1 •b:如果是左括号“(”,则依次弹出 s1 栈顶的运算符,并压入 s2 ,直到遇到右括号为止,此时将这一对括号丢弃
••(6)重复步骤(2)至(5),直到表达式的最左边••(7)将 s1 中剩余的运算符依次弹出并压入 s2••(8)依次弹出 s2 中的元素并输出,结果即为中缀表达式对应的前缀表达式。
例如:中缀表达式 1 (( 2 3 ) × 4) - 5 转为前缀表达式具体过程,如下图
END