栈在表达式求值中的应用

栈在表达式求值中的应用

中缀表达式转后缀表达式

初始化一个栈,用来保存暂还不能确定运算顺序的运算符

从左到右处理各个元素,直到末尾。可能遇到三种情况:

  • 遇到操作数:直接加入后缀表达式
  • 遇到界限符
    • 遇到“(” 直接入栈
    • 遇到“)” 则依次弹出栈内运算符并加入后缀表达式,直到弹出“(”为止
    • 注意:“(”不加入后缀表达式
  • 遇到运算符:依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入后缀表达式,若碰到“(”或栈空则停止。之后再把当前运算符入栈

按上述方法处理完所有字符后,将栈中剩余运算符依次弹出,并加入后缀表达式

例子
A+B*(C-D)-E/F --> ABCD-*+EF/-

detail
stack: null		suffixStr: A			(扫描到A)
stack: +		suffixStr: A			(扫描到+)
stack: +		suffixStr: AB			(扫描到B)
stack: +*		suffixStr: AB			(扫描到*)
stack: +*(		suffixStr: AB			(扫描到"(")
stack: +*(		suffixStr: ABC			(扫描到C)
stack: +*(-		suffixStr: ABC			(扫描到-)
stack: +*(-		suffixStr: ABCD			(扫描到D)
stack: +*		suffixStr: ABCD-		(扫描到")")
stack: -		suffixStr: ABCD-*+		(扫描到-)
stack: -		suffixStr: ABCD-*+E		(扫描到E)
stack: -/		suffixStr: ABCD-*+E		(扫描到/)
stack: -/		suffixStr: ABCD-*+EF	(扫描到F)
stack: null		suffixStr: ABCD-*+EF/-	(扫描到null)
用栈实现后缀表达式的计算

从左往右扫描下一个元素,直到处理完所有元素
②若扫描到操作数则压入栈,并回到①;否则执行③
③若扫描到运算符,则弹出两个栈顶元素,执行相应运算,运算结果压回栈顶,回到①

中缀表达式的计算

初始化两个栈,操作数栈运算符栈

若扫描到操作数压入操作数栈

若扫描到运算符或界限符,则按照 “中缀转后缀” 相同的逻辑压入运算符栈(期间也可以弹出运算符,每当弹出一个运算符时,就需要再弹出两个操作数栈的栈顶元素并执行相应运算,运算结果再压回操作数栈

其实就是 中缀转后缀 + 后缀表达式求值,两个算法的结合

操作数栈:numStack;运算符栈:opStack

A + B - C * D / E + F

detail
numStack: A				opStack: null		(扫描到A)
numStack: A				opStack: +			(扫描到+)
numStack: AB			opStack: +			(扫描到B)
numStack: R				opStack: -			(扫描到-,R=A+B)
numStack: RC			opStack: -			(扫描到C)
numStack: RC			opStack: -*			(扫描到*)
numStack: RCD			opStack: -*			(扫描到D)
numStack: RK			opStack: -/			(扫描到/,K=C*D)
numStack: RKE			opStack: -/			(扫描到E)
numStack: H				opStack: +			(扫描到+,G=K/E,H=R-G)
numStack: HF			opStack: +			(扫描到F)
numStack: Z				opStack: null		(扫描到null, Z=H+F)

注意:先弹出的是,右操作数!!

你可能感兴趣的:(研途KiGo)