华为机试-四则运算(简单)

四则运算

https://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e?tpId=37&tqId=21273&rp=1&ru=%2Fta%2Fhuawei&qru=%2Fta%2Fhuawei%2Fquestion-ranking&tab=answerKey

题目描述

> 输入一个表达式(用字符串表示),求这个表达式的值。 保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。

思路参考:https://leetcode-cn.com/problems/basic-calculator-ii/solution/shi-yong-shuang-zhan-jie-jue-jiu-ji-biao-c65k/

这是一道简单题??? 1、将所有的括号都换成小括号; 2、设置符号栈和数字栈 3、设置函数cal(),对数字栈栈顶的两个元素和符号栈栈顶的一个元素进行运算(注意顺序) 输入遇到前括号- push入符号栈;判断下一位如果是也是符号,则先往数字栈中push一个0; 输入遇到后括号- 直到遇到前括号前,一直进行cal()计算,算出括号内的答案后push入数字栈;此时括号内栈从下往上看优先级是递增的,直接按出栈顺序直接计算后入栈。 输入遇到数字- 向后判断这个数字有多长,截取字符串转换成数字放入数字栈; 输入遇到+-*/符号- 判断该符号与符号栈栈顶符号的优先级,当小于等于的时候进行cal,然后再入栈,否则直接入符号栈。小于是当出现先乘除后加减的情况,等于表示同级运算,应该从左向右,所以先计算栈里的。注意这里是while循环。 4、最后结束循环化,对栈再进行一次while的cal(),输出最后留下的唯一的栈顶。 5、但凡需要循环,判断条件都要注意此时是否是空栈。

#include<iostream>
#include<vector>
#include<stack>
#include <string>
#include <map>
using namespace std;
bool isdigital(char a) {
    return ('0' &lt;= a &amp;&amp; a &lt;= '9') ? true : false;
}
void cal(stack<int>&amp; num, stack<char>&amp; symbol) {//取出数字栈顶的两个元素和符号栈顶的一个符号进行运算
    int a = num.top();
    num.pop();
    int b = num.top();
    num.pop();
    char c = symbol.top();
    symbol.pop();
    int ans;
    switch (c) {//一定要注意是b对a操作
    case '+': {ans = b + a; break; }
    case '-': {ans = b - a; break; }
    case '*': {ans = b * a; break; }
    case '/': {ans = b / a; break; }
    }
    num.push(ans);//计算结果放回栈中

}
int main() {
    string s;
    cin &gt;&gt; s;
    map<char, int> grade;
    grade['('] = 0; grade[')'] = 0; grade['+'] = 1; grade['-'] = 1; grade['*'] = 2; grade['/'] = 2;
    for (int i = 0; i &lt; s.length(); i++) {
        if (s[i] == '{' || s[i] == '[') s[i] = '(';
        if (s[i] == '}' || s[i] == ']') s[i] = ')';
    }
    stack<int> num;
    stack<char> symbol;
    if (!isdigital(s[0])) num.push(0);//避免-5*4这种上来就是符号的
    for (int i = 0; i &lt; s.length(); i++) {
        if (s[i] == '(') {//如果是左括号,入符号栈
            symbol.push('(');
            if (!isdigital(s[i + 1]))//避免(-4+5)这样的情况出现,所以入0
                num.push(0);
        }
        else if (s[i] == ')') {//遇到后括号,则将该括号内式子计算出来
            while (symbol.top() != '(')
                cal(num, symbol);//计算括号里的
            symbol.pop();//左括号弹出
        }
        else if (isdigital(s[i])) {//遇到数字,提取出完整的数字放入数字栈
            int left = i;
            while (i + 1 &lt; s.length() &amp;&amp; isdigital(s[i + 1])) i++;
            num.push(stoi(s.substr(left, i - left + 1)));//也可以ans=ans*10+s[i]算出来
        }
        else //如果是+-*/,当s[i]的优先级小于等于栈顶符号优先级时,对栈顶进行一次计算,直到不符合条件
        {
            while (!symbol.empty() &amp;&amp; grade[s[i]] &lt;= grade[symbol.top()])//注意这里是while不是if,如9-5*4+5;
                cal(num, symbol);
            symbol.push(s[i]);
        }
    }
    while (!symbol.empty())
        cal(num, symbol);
    cout &lt;&lt; num.top();
}
```</char></int></char,></char></int></map></string></stack></vector></iostream>
全部评论
没看懂为什么遇到负号要入0
点赞 回复 分享
发布于 2022-09-28 20:36 北京

相关推荐

来个厂收我吧:首先,市场侧求职我不是很懂。 但是,如果hr把这份简历给我,我会觉得求职人不适合做产品经理。 问题点: 1,简历的字体格式不统一,排版不尽如人意 2,重点不突出,建议参考star法则写个人经历 3,印尼官方货币名称为印度尼西亚卢比(IDR),且GMV690000印尼盾换算为305人民币,总成交额不高。 4,右上角的意向职位在发给其他公司时记得删除。 5,你所有的经历都是新媒体运营,但是你要投市场营销岗位,jd和简历不匹配,建议用AI+提示词,参照多个jd改一下经历内容。 修改建议: 1,统一字体(中文:思源黑体或微软雅黑,英文数字:time new romans),在word中通过表格进行排版(b站学) 2,校招个人经历权重:实习经历=创业经历(大创另算)>项目经历>实训经历>校园经历 3,请将项目经历时间顺序改为倒序,最新的放最上方。 4,求职方向不同,简历文字描述侧重点也需要不同。
点赞 评论 收藏
分享
评论
40
9
分享

创作者周榜

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