栈的经典问题
逆波兰式问题(后缀表达式),括号匹配问题,序列输出问题
逆波兰式
问题概述:
题目给出中缀表达式,要求计算出相应的结果
题目链接
题目思路:
1、中缀表达式转换为后缀表达式
原因:中缀表达式适合人类思维,但计算机很难处理,通常要转化为后缀表达式,利用栈处理
2、计算后缀表达式
中缀转后缀的具体思路:
1、设置操作符栈(通过比较操作符的优先级,确定是否出栈),设置队列来存放后缀表达式
2、扫描遍历中缀表达式,遇到操作数放入队列,遇到操作符则采取下列方式处理:
2.1、如果碰到的操作符优先级高于栈顶操作符优先级,则将碰到的操作符压入栈中
2.2、如果碰到的操作符优先级低于或等于栈顶操作符优先级,则不断出栈,并存入队列,直到碰到的操作符优先级高于栈顶操作符的优先级
2.3、如果碰到括号,遇到左括号直接压入栈中,遇到右括号,不入栈,并且不断弹出栈中操作符,直到碰到左括号,此时抛弃左括号
3、重复上述操作,直到中缀表达式遍历结束,若操作符栈不空,则全部弹出存入队列
题目细节:
1、对于中缀字符串的处理,涉及字符串的分割与拼接
2、后缀表达式需要栈来配合处理,其中弹出的第一个数字是num2,第二个数字是num1
#include <bits/stdc++.h>
using namespace std;
struct node{
double num;
char op;
bool flag;
};
string str;
stack<node> s;
queue<node> q;
map<char, int> op;
//中缀转后缀
void Change()
{
double num;
node temp;
for(int i = 0; i < str.length();)//暂不定义for执行后i的变化情况
{
if(str[i] >= '0' && str[i] <= '9')//是操作数
{
temp.flag = true;
temp.num = str[i++] - '0';
while(i < str.length() && str[i] >= '0' && str[i] <= '9')
{
temp.num = temp.num * 10 + str[i] - '0';
i++;
}
q.push(temp);
}
else//是操作符
{
temp.flag = false;
temp.op = str[i];
//关于括号
if(str[i] == '(')
{
s.push(temp);
i++;
continue;
}
if(str[i] == ')')
{
while(!s.empty() && s.top().op != '(')
{
q.push(s.top());
s.pop();
}
s