题解 | #表达式求值#

表达式求值

https://www.nowcoder.com/practice/c215ba61c8b1443b996351df929dc4d4

Leetcode上有一个类似的224. 基本计算器 但是题目中之要求了'+'和'-',是Hard,我之前做的时候,没有用栈,可以不考虑运算的优先级,直接计算,牛客的该提,是包含乘的,需要考虑运算优先级,所以用了个栈,具体求解看下面(官方题解代码写的是真的烂......)。

/**
 * 根据对应的算法表达式计算结果
 * @param s
 * @return 返回表达式对应的值,表达式包含加减乘,但是感觉除也没啥区别
 */
public int solve (String s) {
    // 特殊处理
    if (s.isEmpty()){
        return 0;
    }
    int res=0,flag=1;
    Stack<Integer> resArr=new Stack<>();

    // 正负号处理:-(2*6)这种特殊情况
    if (s.charAt(0)=='-'){
        flag=-1;
        s=s.substring(1);
    }
    char op='+';
    // 这里没有i++,是因为下面要动态更新i的值,逻辑更清晰。
    for (int i=0;i<s.length();){
        char tmp=s.charAt(i);
        // 更新最近遇到对运算符
        if (tmp=='+'||tmp=='-'||tmp=='*'){
            op=tmp;
            i++;
            // 碰到左括号
        }else if (tmp=='('){
            int j=i+1,num_bracket=1;
            // 将最外层左括号对应对有括号中的表达式当成一个整体进行递归处理
            // 统计括号对数量是因为有可能有括号嵌套:(())
            while (j<s.length()&&num_bracket>0){
                if (s.charAt(j)=='(') {
                    num_bracket++;
                }else if (s.charAt(j)==')'){
                    num_bracket--;
                }
                j++;
            }
            // s.substring()对原始字符串做切割
            calculate(resArr,solve(s.substring(i+1,j-1)),op);
            i=j;

            // 碰到右括号因为上面左括号已经处理过了,直接continue
        }else if (tmp==')'){
            i++;

            // 碰到数字字符
        }else{
            int j=i;
            // 将连续数字字符转成数字:"32233"
            // Character.isDigit()判断给定的char是否是个数字
            while (j<s.length()&&Character.isDigit(s.charAt(j))){
                j++;
            }
            // Integer.parseInt()函数将给定字符串专程int变量
            calculate(resArr,Integer.parseInt(s.substring(i,j)),op);
            i=j;
        }
    }
    // 栈求和,采用Stream流求和代码更优雅
    res= resArr.stream().mapToInt(Integer::intValue).sum();
    return flag*res;
}

/**
 * 根据给定的操作符将对应数字压栈
 * @param resArr {@link Stack<Integer>} 存储Integer类型的Stack
 * @param num int型变量
 * @param op char型变量
 */
public void calculate(Stack<Integer> resArr,int num,char op){
    switch (op){
            // '+' 直接将原始数字压栈
        case '+':
            resArr.add(num);
            break;
            // '-' 将原始数字的相反数压栈
        case '-':
            resArr.add(-num);
            break;
            // '*' 更新栈顶元素与原始数字相乘后压栈
        case '*':
            resArr.push(resArr.pop()*num);
    }
}

全部评论

相关推荐

关于我大学本科四年,想了很多,但还是不知道该怎么动笔&nbsp;“大学四年,是我从懵懂少年走向职场青年的转折期。这一路跌跌撞撞,有迷茫,有遗憾,也有成长和决心。”&nbsp;大一刚进来时仍然有高中那股学习劲,经常一个人去图书馆学高等数学,但后面劲头一过便开始在宿舍开启躺平生活(现在想想那段时间真的很爽,无忧无虑)。由于大一担任班干部,所以经常要跟其他班的班干部交流,在此期间认识了隔壁班的一位女生,短发而很可爱,因为很多团建还有比赛都是我们两班一起参加的,而且我和她都是负责人,所以交集很多,后面慢慢地彼此对产生了好感,所以在大一刚开学的2个月后,我们在一起了,彼此之前都是初恋。但当时我真的是太太太直男了,对感情的想...
真烦好烦真烦:骗哥们可以,别把你自己也骗到了就行。哥们被你骗了真无所谓的,打个哈哈就过了。但希望你打完这段话后擦一下眼角,别让眼泪掉在手机屏幕上了就行。你说的这些话,哥们信一下也是没什么的。还能让你有个心里安慰,但这种话说出来骗骗兄弟就差不多得了,哥们信你一下也不会少块肉,但是你别搞得自己也当真了就行。哥们被你骗一下是真无所谓的,兄弟笑笑也就过去了。真不是哥们想要破你防,你擦擦眼泪好好想想,除了兄弟谁还会信你这些话?
点赞 评论 收藏
分享
牛客ID:561366855:期望薪资多少?难以相信这简历找不到工作。说明二本电子信息专业想对口就业非常难。
点赞 评论 收藏
分享
吐泡泡的咸鱼:我也工作了几年了,也陆陆续续面试过不少人,就简历来说,第一眼学历不太够,你只能靠你的实习或者论文或者项目经历,然后你没有论文,没有含金量高的比赛和奖项,只能看实习和项目,实习来说,你写的实习经历完全不清楚你想找什么工作?行研?数据分析?且写的太少了,再看项目,这些项目先不说上过大学读过研究生的都知道很水,然后对你想找的岗位有什么帮助呢?项目和实习也完全不匹配啊,你好像在努力将你所有的经历都放在简历里想表现你的优秀,但是对于你想找的岗位来说,有什么用呢?最后只能获得岗位不匹配的评价。所以你需要明白你想要找的岗位要求是什么,是做什么的,比如产品经理,然后再看你的经历里有什么匹配的上这个岗位,或者对这个岗位以及这个岗位所在的公司有价值,再写到你的简历上
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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