栈的应用
括号匹配检验
假如有字符串由"(){}[]"这几种括号组成,要你判断该字符串是否合法
步骤:
- 遇到左括号,入栈
- 遇到右括号,如果栈顶元素是右括号对应的左括号,出栈;否则,不合法,直接返回。
汉诺塔问题
直接上代码:
void move(char a, int b, char c){
// 将编号为 b 的圆盘,从 a 移动到 c
}
// 将x上编号为 1~n 的圆盘移动到y, 借助z作为辅助塔
void hanoi(int n, char x, char y,char z){
if(n==1)
move(x,1,z);
else{
hanoi(n-1,x,z,y);
move(x,n,z);
hanoi(n-1,y,x,z);
}
}
int main(){
hanoi(n, x,y,z);
return 0;
}
后缀表达式求值
简单说明:栈只用来保存操作数
步骤:遇到
- 操作数:入栈
- 操作符c:出栈一个为b,再出栈一个为a,计算 a c b的结果,入栈
- 重复,最后结果为栈顶元素
C++代码:
int count(int a, char c, int b){
switch(c){
case '*': return a*b;
case '/': return a/b;
case '+': return a+b;
case '-': return a-b;
}
return 0;
}
bool isOper(string &token){
return token == "*" || token == "/" || token == "+" || token == "-";
}
int value(vector<string> tokens){
stack<int> st;
for(auto &token:tokens){
if(isOper(token)){
int num2 = st.top();st.pop();
int num1 = st.top();st.pop();
st.push(count(num1, token[0], num2));
}else st.push(stoi(token));
}
return st.top();
}
中缀表达式转后缀表达式
讲解
需要用到一个栈,用来存储操作符(括号算界限符,而非操作符)
步骤:
- 操作数:加入后缀表达式
- 界限符:‘(’ 直接入栈;‘)’ 依次弹出栈内运算符,直到 ‘(’,但是两种括号都直接丢弃,不需要加入后缀表达式中
- 运算符:依次弹出栈中高于或等于当前运算符优先级的所有运算符
- 重复,最后直到栈内所有运算符被弹出
代码
运算符优先级定量:
+ | - | * | / | ( | ) | # | |
---|---|---|---|---|---|---|---|
栈内 | 2 | 2 | 4 | 4 | 6 | 1 | |
栈外 | 3 | 3 | 5 | 5 | 6 | 1 | 1 |
中缀表达式求值
后缀表达式求值 + 中缀表达式转后缀表达式 = 中缀表达式求值
讲解
需要两个栈,一个操作数栈,一个操作符栈(简称数栈和符栈)。
步骤:
- 操作数:入数栈
- 界限符:同中缀转后缀的步骤
- 操作符:同中缀转后缀的步骤
- 操作符出栈:运算数栈栈顶的两个操作数,并且结果入数栈
- 直到扫描完成以及符栈为空
- 结果为数栈顶部元素