栈的应用——表达式求值
栈在数据结构中应用非常广泛,表达式求值就是最典型的例子之一。
1、 “表达式” = “第一操作数” + “运算符” + “第二操作数”
“操作数” = “简单变量” | “表达式”
“简单变量” = “标识符” | “无符号整数”
2、 exp:a*b+(c-d/e)*f
注意:前缀、中缀和后缀表示法都没有括弧
(1)前缀表示法:+*ab*-c/def
连续出现的两个操作数和在它们之前且紧靠它们的运算符构成一个最小表达式;前缀式唯一的确定了运算次序;
(2)中缀表示法:a*b+c-d/e*f
中缀式丢失了括弧信息,致使运算的次序不确定;
(3)后缀表示法:ab*cde/-f*+
运算符在式中出现的顺序恰为表达式的运算次序(因此,后缀式应用最为广泛);每个运算符和在它之前出现且紧靠它的两个操作数构成一个最小表达式。
结论:(1)操作数之间的相对次序不变;
(2)运算符的相对次序不同(中缀相同,但没有括弧);
3、 如何从后缀式求原表达式的值?
先找运算符,再找操作数。
需要一个栈,依次遍历后缀式字符,遇到操作数就进栈,遇到运算符就取出栈顶第二操作数,再取出栈顶第一操作数,两个操作数和一个运算符一起构成一个最小表达式,即成为一个操作数再次进栈。以此类推……
_________________________________________________________________________
exp: ab*cde/-f*+
stack:| a | | | |
| a | b | | |
| a*b | c | | |
| a*b | c | d | |
| a*b | c | d | e |
| a*b | c | d/e | |
| a*b | c-d/e | | |
| a*b | c-d/e | f | |
| a*b | (c-d/e)*f | | |
| a*b + (c-d/e)*f | | | |
最后栈底的元素就是表达式的值!
___________________________________________________________________________
4、如何从原表达式求后缀式?
需要一个栈,存储运算符(为了始终可比,可在栈底放‘#’,规定‘#’优先级最低),遇到操作数直接送入后缀式。
每一个运算符的运算次序要由它之后的一个运算符来定,在后缀式中,优先数高的运算符领先于优先数低的运算发。具体步骤为:
(1)设立运算符栈;
(2)设表达式的结束符为'#' , 预设运算符栈的栈底为‘#’;
(3)若当前字符是操作数,则直接发给后缀式;
(4)若当前运算符的优先级高于栈顶运算符,则进栈;
(5)否则,推出栈顶运算符发给后缀式;
(6)‘(’ 对它之后的运算符起隔离作用,‘)’ 可视为自相应左括弧开始的表达式;
上代码……
栈在数据结构中应用非常广泛,表达式求值就是最典型的例子之一。
1、 “表达式” = “第一操作数” + “运算符” + “第二操作数”
“操作数” = “简单变量” | “表达式”
“简单变量” = “标识符” | “无符号整数”
2、 exp:a*b+(c-d/e)*f
注意:前缀、中缀和后缀表示法都没有括弧
(1)前缀表示法:+*ab*-c/def
连续出现的两个操作数和在它们之前且紧靠它们的运算符构成一个最小表达式;前缀式唯一的确定了运算次序;
(2)中缀表示法:a*b+c-d/e*f
中缀式丢失了括弧信息,致使运算的次序不确定;
(3)后缀表示法:ab*cde/-f*+
运算符在式中出现的顺序恰为表达式的运算次序(因此,后缀式应用最为广泛);每个运算符和在它之前出现且紧靠它的两个操作数构成一个最小表达式。
结论:(1)操作数之间的相对次序不变;
(2)运算符的相对次序不同(中缀相同,但没有括弧);
3、 如何从后缀式求原表达式的值?
先找运算符,再找操作数。
需要一个栈,依次遍历后缀式字符,遇到操作数就进栈,遇到运算符就取出栈顶第二操作数,再取出栈顶第一操作数,两个操作数和一个运算符一起构成一个最小表达式,即成为一个操作数再次进栈。以此类推……
_________________________________________________________________________
exp: ab*cde/-f*+
stack:| a | | | |
| a | b | | |
| a*b | c | | |
| a*b | c | d | |
| a*b | c | d | e |
| a*b | c | d/e | |
| a*b | c-d/e | | |
| a*b | c-d/e | f | |
| a*b | (c-d/e)*f | | |
| a*b + (c-d/e)*f | | | |
最后栈底的元素就是表达式的值!
___________________________________________________________________________
4、如何从原表达式求后缀式?
需要一个栈,存储运算符(为了始终可比,可在栈底放‘#’,规定‘#’优先级最低),遇到操作数直接送入后缀式。
每一个运算符的运算次序要由它之后的一个运算符来定,在后缀式中,优先数高的运算符领先于优先数低的运算发。具体步骤为:
(1)设立运算符栈;
(2)设表达式的结束符为'#' , 预设运算符栈的栈底为‘#’;
(3)若当前字符是操作数,则直接发给后缀式;
(4)若当前运算符的优先级高于栈顶运算符,则进栈;
(5)否则,推出栈顶运算符发给后缀式;
(6)‘(’ 对它之后的运算符起隔离作用,‘)’ 可视为自相应左括弧开始的表达式;
上代码……
——————————————————————————————————————————