题解 | #四则运算#

四则运算

https://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e

#include <iostream>
using namespace std;
#include <string>
#include <stack>
#include <cctype>
#include <map>

void caculate(stack<int>& numS, stack<char>& opS) {
    int num2 = numS.top();
    numS.pop();
    int num1 = numS.top();
    numS.pop();
    char op = opS.top();
    opS.pop();
    switch (op) {
        case '+':
            numS.push(num1 + num2);
            break;
        case '-':
            numS.push(num1 - num2);
            break;
        case '*':
            numS.push(num1 * num2);
            break;
        case '/':
            numS.push(num1 / num2);
            break;
    }
}

int main() {
    string str;
    // 双栈法解决
    stack<int> numS;
    stack<char> opS;
    // 设置计算符优先级
    map<char, int> m;
    m.insert(pair<char, int>('+', 0));
    m.insert(pair<char, int>('-', 0));
    m.insert(pair<char, int>('*', 1));
    m.insert(pair<char, int>('/', 1));
    m.insert(pair<char, int>('(', -1));
    getline(cin, str);
    int lastType = 0; // 记录上一个入栈的数据类型,用于识别负数
    for (int i = 0; i < str.size(); i++) {
        if (isdigit(str[i])) {
            int b = i;
            while (isdigit(str[i])) {
                i++;
            }
            string str2(str.begin() + b, str.begin() + i);
            int num = stoi(str2);
            numS.push(num);
            i--;
            lastType = 1;
        } else if (str[i] == '(' || str[i] == '[' || str[i] == '{') {
            opS.push('(');
            lastType = 0;
        } else if (str[i] == ')' || str[i] == ']' || str[i] == '}') {
            while (opS.top() != '(') {
                caculate(numS, opS);
            }
            opS.pop();
        } else if (str[i] == '-') {
            if (lastType == 1) {
                while (!opS.empty() && m[opS.top()] >= m[str[i]]) {
                    caculate(numS, opS);
                }
                opS.push(str[i]);
                lastType = 0;
            } else if (lastType == 0) {
                i++;
                int b = i;
                while (isdigit(str[i])) {
                    i++;
                }
                string str2(str.begin() + b, str.begin() + i);
                int num = 0 - stoi(str2);
                numS.push(num);
                i--;
                lastType = 1;
            }
        } else {
            while (!opS.empty() && m[opS.top()] >= m[str[i]]) {
                caculate(numS, opS);
            }
            opS.push(str[i]);
            lastType = 0;
        }
    }
    while (!opS.empty()) {
        caculate(numS, opS);
    }

    cout << numS.top() << endl;
}

双栈法,这里讲几个要点

第一:输入的数字不止个位数,要做好转化,这里用了str的一个构造方法;

第二:每准备入栈一个新的非左括号运算符之前,要判断一下这个新运算符与当前栈顶运算符的优先级,如果栈顶的运算符优先级大于或等于(一定要有等于)这个新运算符的优先级,则用这个栈顶符号做一次运算;运算过程可以写一个函数,优先级可以使用一个map;

第三:对于负数的读入,写一个标志位,如果上一个输入的符号为数字,则该‘-’符号是运算符;如果上一个输入的符号为运算符,则该‘-’符号代表负数的前缀;初始标志位为上一次输入为符号的状态;

第四:在字符串读入完成后,继续运算直到运算符栈为空后输出数字栈的栈顶元素即可。

建议理解的时候在纸张上画出栈帮助理解运行过程。

华为机试刷题记录 文章被收录于专栏

记录一下手打代码的解题思路方便复习

全部评论

相关推荐

刚刷到字节跳动官方发的消息,确实被这波阵仗吓了一跳。在大家还在纠结今年行情是不是又“寒冬”的时候,字节直接甩出了史上规模最大的转正实习计划——ByteIntern。咱们直接看几个最硬的数,别被花里胡哨的宣传词绕晕了。首先是“量大”。全球招7000多人是什么概念?这几乎是把很多中型互联网公司的总人数都给招进来了。最关键的是,这次的资源分配非常精准:研发岗给了4800多个Offer,占比直接超过六成。说白了,字节今年还是要死磕技术,尤其是产品和AI领域,这对于咱们写代码的同学来说,绝对是今年最厚的一块肥肉。其次是大家最关心的“转正率”。官方直接白纸黑字写了:整体转正率超过50%。这意味着只要你进去了,不划水、正常干,每两个人里就有一个能直接拿校招Offer。对于2027届(2026年9月到2027年8月毕业)的同学来说,这不仅是实习,这简直就是通往大厂的快捷通道。不过,我也得泼盆冷水。坑位多,不代表门槛低。字节的实习面试出了名的爱考算法和工程实操,尤其是今年重点倾斜AI方向,如果你简历里有和AI相关的项目,优势还是有的。而且,转正率50%也意味着剩下那50%的人是陪跑的,进去之后的考核压力肯定不小。一句话总结:&nbsp;27届的兄弟们,别犹豫了。今年字节这是铁了心要抢提前批的人才,现在投递就是占坑。与其等到明年秋招去千军万马挤独木桥,不如现在进去先占个工位,把转正名额攥在手里。
喵_coding:别逗了 50%转正率 仔细想想 就是转正与不转正
字节7000实习来了,你...
点赞 评论 收藏
分享
零零幺零零幺:至少再做一个项目,然后猛投小厂,不然有点难
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务