题解 | #表达式求值# 两个栈分别保存数值和运算符

表达式求值

https://www.nowcoder.com/practice/9566499a2e1546c0a257e885dfdbf30d

题解思路:感觉处理这种题一定要先弄明白算术运算的逻辑,包括对负数和括号的处理。如果了解中缀表达式如何转后缀表达式,那处理这个问题的思路就很清晰了。难点是对于负数的处理。我的解决方法是:定义两个栈,分别用于保存数值和运算符。保存数值时需要对负数进行判断。保存运算符时,只有当运算符栈的栈顶为* 或 / 的时候再出栈处理,先处理乘除再处理加减。遇到左括号时,直接入栈即可,只有当遇到右括号再出栈处理。写的很仓促,也没有再优化,哪里不对的地方希望朋友们指正!
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
import java.util.Stack;
public class Main {
    public static void main(String[] args) throws IOException {
        InputStream in = System.in;
        Scanner scanner = new Scanner(in);
        String str = scanner.nextLine();
        int result = getEvaluation(str);
        System.out.println(result);
    }
     private static int getEvaluation(String str) {
        if (str == null || str.length() == 0) return 0;
        // 记录数值
        Stack<Integer> arithmetic = new Stack<>();
        // 记录运算符
        Stack<Character> operator = new Stack<>();
        int i = 0;
        while(i < str.length()) {
            // 处理负数
            boolean negative = false;
            if ((str.charAt(i) == '-' && arithmetic.isEmpty()) ||
                    (str.charAt(i) == '-' && !(str.charAt(i-1) >= '0' && str.charAt(i-1) <= '9') && str.charAt(i-1) != ')')) {
                negative = true;
                i++;
            }
            // 保存数值
            if (i < str.length() && str.charAt(i)  >= '0' && str.charAt(i) <= '9'){
                StringBuilder builder = new StringBuilder();
                while (i < str.length() && str.charAt(i)  >= '0' && str.charAt(i) <= '9'){
                    builder.append(str.charAt(i));
                    i++;
                }
                arithmetic.push(negative ? -Integer.valueOf(builder.toString()) : Integer.valueOf(builder.toString()));
            }
            // 出栈处理数值
            if (i < str.length() && (str.charAt(i) == '+' || str.charAt(i) == '-')) {
                while (!operator.isEmpty() && (operator.peek() == '*' || operator.peek() == '/')) {
                    Character op = operator.pop();
                    Integer n1 = arithmetic.pop();
                    Integer n2 = arithmetic.pop();
                    arithmetic.push(operation(n2, n1, op));
                }
                while (!operator.isEmpty() && (operator.peek() == '+' || operator.peek() == '-')){
                        Character op = operator.pop();
                        Integer n1 = arithmetic.pop();
                        Integer n2 = arithmetic.pop();
                        arithmetic.push(operation(n2, n1, op));
                    }
                operator.push(str.charAt(i));
                i++;
            }
            // 遇到右括号再出栈处理
            else if (i < str.length() && (str.charAt(i) == ')')){
               while (true){
                   Character op = operator.pop();
                   if (op == '(') break;
                   Integer n1 = arithmetic.pop();
                   Integer n2 = arithmetic.pop();
                   arithmetic.push(operation(n2,n1,op));
               }
               i++;
            }
            // 运算符入栈
            else{
                if (i == str.length())
                    break;
                operator.push(str.charAt(i));
                i++;
            }
        }
        while (!operator.isEmpty()){
            Character op = operator.pop();
            Integer n1 = arithmetic.pop();
            Integer n2 = arithmetic.pop();
            arithmetic.push(operation(n2,n1,op));
        }
        return arithmetic.pop();
    }

    /**
     * 基础运算
     */
    private static Integer operation(Integer n1, Integer n2, Character op) {
        if (op == '+')
            return n1 + n2;
        else if (op == '-')
            return n1 - n2;
        else if (op == '*')
            return n1 * n2;
        else
            return n1 / n2;
    }
}


#笔试刷题##华为OD#
全部评论

相关推荐

不愿透露姓名的神秘牛友
06-21 11:33
昨天是学校最后一场招聘会,鼠鼠去参加了,全场只有一个招聘java的岗位,上来先做一份笔试题,做完后他拿张纸对答案,然后开始问简历上的问题,深圳小厂,6-8k(题目如下),后面还有两轮面试。然后我就在招聘现场逛呀逛,看到有公司招聘电商运营,给的比上年的小厂还多,鼠鼠就去了解了下,然后hr跟鼠鼠要了份简历,虽然我的简历上面全是求职Java开发相关的内容,但是hr还是鼓励我说没关系,她帮我把简历给老板看看,下周一会给我通知。招聘会结束后鼠鼠想了一段时间,也和朋友聊了聊,发现我可能是不太适合这个方向,然后就跟爸爸说回家了给我发条微信,我有些话想跟他说说。晚上爸爸到家了,跟我发了条微信,我立马跑出图书馆跟他打起了电话,这个通话长达一个小时,主要是跟爸爸坦白说我不想找这行了,是你的儿子太没用了,想试试其他行业。然后爸爸也跟我说了很多,说他从来没有希望我毕业后就赚大钱的想法,找不到就回家去,回家了再慢慢找,实在找不到就跟他干(帮别人装修房子,个体户),他也知道工作不好找,让我不要那么焦虑,然后就是聊一些家常琐事。对于后面的求职者呢我有点建议想提一下,就是如果招实习的时间或者秋招开始,而你的简历又很差的情况下,不要说等做好项目填充完简历之后再投,那样就太晚了,建议先把熟悉的项目写上简历,然后边投边面边完善,求职是一个人进步的过程,本来就比别人慢,等到一切都准备好后再投岂不是黄花菜都凉了。时间够的话还是建议敲一遍代码,因为那样能让你加深一下对项目的理解,上面那些说法只是针对时间不够的情况。当然,这些建议可能没啥用,因为我只是一个loser,这些全是建立在我理想的情况下,有没有用还需其他人现身说法。上篇帖子没想到学校被人认了出来,为了不丢脸只能匿名处理了。
KPLACE:找研发类或技术类,主要还是要1.多投 2.多做准备,很多方面都要做准备 3.要有心理准备,投累了就休息一两天,再继续,要相信自己能找到
投递58到家等公司7个岗位
点赞 评论 收藏
分享
求offer的大角牛:不吃香菜
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
2
1
分享

创作者周榜

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