leetcode 面试题 16.26.计算器

原题

面试题 16.26.计算器
在这里插入图片描述

题解

方法一 转化为若干数字的和

总说:
在多则运算中,乘法和除法的优先级比加减法要高,因此在运算的时候,我们要先把数字两边有乘除号的那些数字看做整体优先运算出结果,然后再把所有代表结果的数字的数字相加就是最终的结果。
思路步骤:
1、 首先建立一个ArrayList list来存储所有待加的数字(当然如果某个数字或者某个乘除字符段之前是减号,那我们在存入数字的实后可以去相反数,这一点在下面步骤4会提到的);
2、 利用一个变量i作为指针,从头到尾来遍历s的所有字符,当然在开始遍历之前,要把s处理成前后都没有空格的字符串,这样可以减少麻烦;利用变量shuzi(每一次处理完后,shuzi会被初始化为0)来记录运算符之间的数字,利用变量fuhao来记录之前最后出现的运算符(对应关系为:0+、1-、2*、3/),以便知道在将数字放入list或者修改list中的数字之时的具体操作;
3、 先说一下,当i指向的位置是数字的时候,我们需要先把这一位字符和转换成整型数,当然这一位数字可能不是单独的一位数,那么我们就需要根据十进制来进行处理(比如32,i指向3的时候,首先shuzi被赋予了3,当下一轮循环,i指向2的时候,我们需要把shuzi的值乘10在加上2);而如果我们在某时已经遍历到s的最后一位了,就需要也把此时得到的shuzi,进行步骤4里面的处理;
4、 现在说i指向的位置时运算符号。我们遇到运算符号的时候,首先要考虑在这个运算符号之前的遇到的上一个运算符号是什么,因为这关系到了我们此时如何处理现在得到的变量shuzi。上一个运算符符号是什么,我利用了变量fuhao以0-3的数字来表示:

  • 当fuhao==0的时候,也就是加号+,意味着当前的shuzi在式子中作为加数,因此直接加入list;
  • 当fuhao==1的时候,也就是减号-,意味着当前的shuzi在式子中作为减数数,因此取反后加入list;
  • 当fuhao==2的时候,也就是乘号*,意味着当前的shuzi是和已加入list的最后一个数作了乘法运算,需要修改list里面最后的数字的值,乘上shuzi
  • 当fuhao==3的时候,也就是除号*,意味着当前的shuzi是和已加入list的最后一个数作了除法运算,需要修改list里面最后的数字的值,除以shuzi

当然每一次经过步骤4之后,都需要初始化shuzi为0,以便于后边继续利用它处理后边的内容。
5、 最后一步,把list里面的所有数加起来得到最后结果,就想做简单的加法题一样。
本思路java代码示例:

/*
@v7fgg
执行用时:22 ms, 在所有 Java 提交中击败了41.89%的用户
内存消耗:40.3 MB, 在所有 Java 提交中击败了100.00%的用户
2020年7月15日 14:55
*/
class Solution {
    public int calculate(String s) {
        s=s.trim();
        List<Integer> list=new ArrayList<>();
        int i=0;//指针
        int shuzi=0;//记录每两个运算符之间的数字
        int fuhao=0;//记录上一个运算符是什么:0+、1-、2*、3/
        while(i<s.length()){
            //对于空格就跳过直到不是为止
            while(s.charAt(i)==' '){
                i++;
            }
            //对于数字,要用逐位乘10相加的方法算出具体值
            if(s.charAt(i)>='0'&&s.charAt(i)<='9'){
                shuzi=10*shuzi+s.charAt(i)-'0';
                //特殊情况假如已经到达字符串末端,则要把最后一个数的运算结果归档
                if(i==s.length()-1){
                    if(fuhao==0){list.add(shuzi);}
                    else if(fuhao==1){list.add(-shuzi);}
                    else if(fuhao==2){
                        list.set(list.size()-1,shuzi*list.get(list.size()-1));
                    }
                    else{
                        list.set(list.size()-1,list.get(list.size()-1)/shuzi);
                    }
                }
            }
            //而对于运算符号,需要先把前面得到数字归档
            else{
                if(fuhao==0){list.add(shuzi);}
                else if(fuhao==1){list.add(-shuzi);}
                //乘除比较特殊,要把list里面最后的数字进行修改
                else if(fuhao==2){
                    list.set(list.size()-1,shuzi*list.get(list.size()-1));
                }
                else{
                    list.set(list.size()-1,list.get(list.size()-1)/shuzi);
                }
                shuzi=0;//变量shuzi要初始化
                if(s.charAt(i)=='+'){fuhao=0;}
                else if(s.charAt(i)=='-'){fuhao=1;}
                else if(s.charAt(i)=='*'){fuhao=2;}
                else{fuhao=3;}
            }
            i++;
        }
        int ans=0;
        for(int j=0;j<list.size();j++){
            ans+=list.get(j);
        }
        return ans;   
    }
}

当然我们也可以不用ArrayList,改用Stack,解题的原理还是一样的。
利用Stack代码示例:

/*
@v7fgg
执行用时:18 ms, 在所有 Java 提交中击败了52.12%的用户
内存消耗:40.8 MB, 在所有 Java 提交中击败了100.00%的用户
2020年7月15日 15:13
*/
class Solution {
    public int calculate(String s) {
        s=s.trim();
        Stack<Integer> stack=new Stack<>();
        int i=0;//指针
        int shuzi=0;//记录每两个运算符之间的数字
        int fuhao=0;//记录上一个运算符是什么:0+、1-、2*、4/
        while(i<s.length()){
            //对于空格就跳过直到不是为止
            while(s.charAt(i)==' '){
                i++;
            }
            //对于数字,要用逐位乘10相加的方法算出具体值
            if(s.charAt(i)>='0'&&s.charAt(i)<='9'){
                shuzi=10*shuzi+s.charAt(i)-'0';
                //特殊情况假如已经到达字符串末端,则要把最后一个数的运算结果归档
                if(i==s.length()-1){
                    if(fuhao==0){stack.push(shuzi);}
                    else if(fuhao==1){stack.push(-shuzi);}
                    else if(fuhao==2){
                        stack.push(shuzi*stack.pop());
                    }
                    else{
                        stack.push(stack.pop()/shuzi);
                    }
                }
            }
            //而对于运算符号,需要先把前面得到数字归档
            else{
                if(fuhao==0){stack.push(shuzi);}
                else if(fuhao==1){stack.push(-shuzi);}
                else if(fuhao==2){
                    stack.push(shuzi*stack.pop());
                }
                else{
                   stack.push(stack.pop()/shuzi);
                }
                shuzi=0;//变量shuzi要初始化
                if(s.charAt(i)=='+'){fuhao=0;}
                else if(s.charAt(i)=='-'){fuhao=1;}
                else if(s.charAt(i)=='*'){fuhao=2;}
                else{fuhao=3;}
            }
            i++;
        }
        int ans=0;
        while(!stack.empty()){
            ans+=stack.pop();
        }
        return ans;   
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可爱抱抱呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值