当前位置:   article > 正文

栈的应用——括号、前缀后缀表达式_有括号的后缀表达式

有括号的后缀表达式

1.括号匹配问题

(((()))) ()()(())

最后出现的左括号会最先匹配(LIFO)所有括号都可以两两配对。

每出现一个右括号,就消耗一个左括号,出栈操作

遇到左括号就入栈,遇到右括号就“消耗”一个左括号出栈。

  1. #define MaxSize 10
  2. #include <Stack.cpp>
  3. bool bracketChechk(char str[], int length){
  4. SqStack S;
  5. InitStack(S);
  6. for(int i=0; i<length; i++){
  7. if(str[i] == '(' ||str[i] == '['||str[i] == '{'){
  8. Push(S,str[i]);
  9. }else{
  10. if(StackEmpty(S))
  11. return false;
  12. char topElem;
  13. Pop(S,topElem);
  14. if(str[i]==')' && topElem !='(')
  15. return false;
  16. if(str[i]==']' && topElem !='[')
  17. return false;
  18. if(str[i]=='}' && topElem !='{')
  19. return false;
  20. }
  21. }
  22. return StackEmpty(S);
  23. }

以上代码建立在栈基本操作基础上,可以看我专栏之前文章找栈。

2.算数表达式

eg:((15/(7-(1+1)))*3)-(2+(1+1))

由三个部分组成:操作数、运算符、界限符

在传统式子中,界限符是不可缺少的,它反映了计算的先后顺序

某波兰数学家想到了不用界限符,无歧义表达运算顺序

Reverse Polish  notation (逆波兰表达式=后缀表达式)

Polish notation(波兰表达式=前缀表达式)

中缀表达式 运算符在两个操作数中间  a+b   a+b-c         a+b-c*d

后缀表达式 运算符在两个操作数后面 ab+   ab+c-/abc-+    ab+ cd* -

前缀表达式 运算符在两个操作数之前 +ab   -+abc            -+ab*cd

(一个新的颜色可以理解为形成的一个新的数)

中缀转后缀:

由于转换可以由很多种,但算法有确定性,为保证运算顺序唯一,

所以转换时最好遵循左优先原则,只要左边能先计算,就优先算左边的)

同理后缀表达式手算方法:

从左往右扫描,每遇到一个运算符,就让运算符前面最近的两个操作数执行对应运算,合体为一个操作数。(注意除法之类的左右顺序)

中缀转前缀:

【运算符 左操作数 右操作数】组成新操作数

遵循 右优先原则 

3.用栈实现中缀转后缀

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

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

(1)遇到操作数,直接加入后缀表达式

(2)遇到界限符, 遇到“(”直接入栈, 遇到“)”则依次餐厨栈内运算符并加入后缀表达式,直到弹出“( ”为止,注意:“(”不加入后缀表达式

(3)遇到运算符。依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入后缀表达式,若碰到“(”或栈空则停止。之后再把当前运算符入栈

最后,将栈中所有运算符弹出,并加入后缀表达式

4.用栈实现中缀表达式求值

(中缀转后缀+后缀表达式求和)

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

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

扫描到运算符或界限符,则按照“中缀转后缀”相同逻辑压入运算符栈

(期间也会弹出运算符。每当弹出一个运算符时,就需要弹出两个操作数栈的栈顶元素并执行相应运算,运算结果再压回操作数栈)

懒得写代码.jpg

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/952436
推荐阅读
相关标签
  

闽ICP备14008679号