曾经沧海难为水,除却巫山不是云。|

Joey-Wang

园龄:4年3个月粉丝:17关注:0

7.1 栈的应用

7.1 栈的应用

http://codeup.hustoj.com/contest.php?cid=100000605

6.8 stack的常见用法详解与此节题目相同

A 简单计算器

image-20200803214737346

题目解析

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

image-20200803215233202

题目解析

定义栈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 中国大陆许可协议进行许可。

posted @   Joey-Wang  阅读(64)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开