赞
踩
(((()))) ()()(())
最后出现的左括号会最先匹配(LIFO)所有括号都可以两两配对。
每出现一个右括号,就消耗一个左括号,出栈操作
遇到左括号就入栈,遇到右括号就“消耗”一个左括号出栈。
- #define MaxSize 10
- #include <Stack.cpp>
-
-
- bool bracketChechk(char str[], int length){
- SqStack S;
- InitStack(S);
- for(int i=0; i<length; i++){
- if(str[i] == '(' ||str[i] == '['||str[i] == '{'){
- Push(S,str[i]);
- }else{
- if(StackEmpty(S))
- return false;
- char topElem;
- Pop(S,topElem);
- if(str[i]==')' && topElem !='(')
- return false;
- if(str[i]==']' && topElem !='[')
- return false;
- if(str[i]=='}' && topElem !='{')
- return false;
- }
- }
- return StackEmpty(S);
-
- }
以上代码建立在栈基本操作基础上,可以看我专栏之前文章找栈。
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
(一个新的颜色可以理解为形成的一个新的数)
中缀转后缀:
由于转换可以由很多种,但算法有确定性,为保证运算顺序唯一,
所以转换时最好遵循左优先原则,只要左边能先计算,就优先算左边的)
同理后缀表达式手算方法:
从左往右扫描,每遇到一个运算符,就让运算符前面最近的两个操作数执行对应运算,合体为一个操作数。(注意除法之类的左右顺序)
中缀转前缀:
【运算符 左操作数 右操作数】组成新操作数
遵循 右优先原则
初始化一个栈,用于保存暂时还不能确定运算顺序的运算符。
从左到右处理各种元素,直到末尾。可能遇到三种情况:
(1)遇到操作数,直接加入后缀表达式
(2)遇到界限符, 遇到“(”直接入栈, 遇到“)”则依次餐厨栈内运算符并加入后缀表达式,直到弹出“( ”为止,注意:“(”不加入后缀表达式
(3)遇到运算符。依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入后缀表达式,若碰到“(”或栈空则停止。之后再把当前运算符入栈
最后,将栈中所有运算符弹出,并加入后缀表达式
(中缀转后缀+后缀表达式求和)
初始化两个栈,操作数栈和运算符栈
扫描到操作数——压入操作数栈
扫描到运算符或界限符,则按照“中缀转后缀”相同逻辑压入运算符栈
(期间也会弹出运算符。每当弹出一个运算符时,就需要弹出两个操作数栈的栈顶元素并执行相应运算,运算结果再压回操作数栈)
懒得写代码.jpg
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。