7.1 栈的应用
7.1 栈的应用
http://codeup.hustoj.com/contest.php?cid=100000605
6.8 stack的常见用法详解
与此节题目相同
A 简单计算器

题目解析
emmmmm代码注释很清楚,标注⚠️的地方都是写代码的时候漏掉的,要注意!!!
一开始没有写node结构体,但是考虑到如果不管操作数还是操作符都用char表示的话,操作数最大为127而且不能有浮点数,这显然是不可能的,所以还是改成了node结构体。
【书p147也有此题解析和代码,可参考】
代码
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <algorithm>
#include <stack>
using namespace std;
struct node {
double num;
char op;
bool flag; //为true表示为操作符,false为操作符
};
stack<node> s; //在change函数中用于存放放操作符,在calculate函数中存放操作数
queue<node> q; //存放后缀表达式
map<char, int> mp;//操作符优先级
string str; //读入的中缀表达式
//将中缀表达式转换为后缀表达式
void change() {
//遍历中缀表达式
for (int i = 0; i < str.length();) {
node temp;
//若是操作数,则加入q
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') { //i < str.length()很重要!!!⚠️
temp.num = temp.num * 10 + str[i] - '0'; //因为这个操作数不一定只有一位
i++;
}
q.push(temp);
}
//是操作符
else {
temp.flag = false;
temp.op = str[i];
//若操作符优先级 <= 栈顶优先级,则不停出栈
while (!s.empty() && mp[str[i]] <= mp[s.top().op]) { // !s.empty() 很重要!!!⚠️
q.push(s.top());
s.pop();
}
s.push(temp);
i++;
}
}
// 若s中还有操作符,则加入后缀表达式
while (!s.empty()) {
q.push(s.top());
s.pop();
}
}
//计算后缀表达式,最后s中的数为最终结果
double calculate() {
//遍历后缀表达式
while (!q.empty()) {
node temp = q.front();
q.pop(); //别忘了!!!⚠️
//为操作数,则压栈
if (temp.flag) {
s.push(temp);
}
//为操作符,则出栈两个进行计算,然后结果压栈
else {
node a, b, c;
c.flag = true;
b = s.top();
s.pop();
a = s.top();
s.pop();
if (temp.op == '+') c.num = a.num + b.num;
else if (temp.op == '-') c.num = a.num - b.num;
else if (temp.op == '*') c.num = a.num * b.num;
else c.num = a.num / b.num;
s.push(c);
}
}
return s.top().num;
}
int main() {
mp['+'] = 1, mp['-'] = 1;
mp['*'] = 2, mp['/'] = 2;
while (getline(cin, str) && str != "0") {
//将str的所有空格都去掉
for (string::iterator it = str.begin(); it != str.end(); it++) {
if (*it == ' ') str.erase(it);
}
change();
printf("%.2f\n", calculate());
s.pop(); //因为s最后还有一个数字,要清空s
}
return 0;
}
B Problem E

题目解析
定义栈stack,遍历输入的字符串。
- 若是 (、[、{ 肯定要入栈;
- 若是 )、]、},若栈为空则return false;若栈不为空,但与栈顶元素不匹配,则return false
- 遍历完后,若stack为空,证明都匹配完全 return true;否则证明有多余的符号,return false【故可简化为return stack.empty() 】
⚠️ 使用getline时,因为getline可以读入空格,故若前面使用了scanf,要先用getchar吸收掉换行
代码
#include <iostream>
#include <cstdio>
#include <string>
#include <stack>
using namespace std;
string str;
stack<char> s;
bool match(char a, char b) {
if (a == '(' && b == ')') return true;
else if (a == '[' && b == ']') return true;
else if (a == '{' && b == '}') return true;
else return false;
}
bool deal() {
for (int i = 0; i < str.length(); i++) {
if (str[i] == '(' || str[i] == '[' || str[i] == '{') s.push(str[i]);
else if (str[i] == ')' || str[i] == ']' || str[i] == '}') {
if (s.empty()) return false;
else if (!match(s.top(), str[i])) return false;
else s.pop();
}
}
return s.empty();
}
int main() {
int n;
while (scanf("%d", &n) != EOF) {
getchar();
while(n--){
getline(cin, str);
if (deal()) printf("yes\n");
else printf("no\n");
while(!s.empty()) s.pop();//别忘了最后要清空stack,因为下一次还要用的
}
}
return 0;
}
本文作者:Joey-Wang
本文链接:https://www.cnblogs.com/joey-wang/p/14541178.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步