calculate-基本计算题

题意:

实现一个基本的计算器来计算一个简单的字符串表达式 s 的值。

示例 1:

输入:s = “1 + 1”
输出:2

示例 2:

输入:s = " 2-1 + 2 "
输出:3

示例 3:

输入:s = “(1+(4+5+2)-3)+(6+8)”
输出:23

提示:

1 <= s.length <= 3 * 105
s 由数字、’+’、’-’、’(’、’)’、和 ’ ’ 组成
s 表示一个有效的表达式

Related Topics 栈 数学

解题思路

  • 建立一个栈,只要不是’)‘,我们就将s的每一个元素挨个放入其中
  • 遇到’)‘,则将最近位置的‘(’之间的字符串,求运算,结果重新入栈,取代‘(’
  • 最后栈中是一个没有‘(’,’)'的字符串
  • 求出栈中结果
    本题为困难题,请想看下面的代码演示中的代码注释部分。

代码演示

class Solution {
    public int calculate(String s) {
        //建stringbuilder,用来模拟栈
          StringBuilder sb=new StringBuilder();
          //循环整个字符串,将符合要求的字符放入sb中
          for(char ch:s.toCharArray())
          {
              //如果当前字符不是')',那么我们将这个字符入‘栈’,-之后的栈就不打引号了,意为不是真正意义上的栈

              if(ch!=')')
              {
                  //按照题目中有可能给空格,我们将空格都跳过(没有实质的意义),再将元素放入到队列中
                  if(ch==' ')
                      continue;
                  sb.append(ch);
              }
              //当匹配到')'的时候,我们执行如下操作,大致的概括就是将')'和与之匹配的'('之间的元素求和,得到的结果重新放入到队列中
              else
              {
                  int sum=0;
                  //得到对应'('的位置
                  int index = sb.lastIndexOf("(");
                  //调用sumCount()方法,求出')'和与之匹配的'('之间的元素的和
                  sum=sumCount(sb,index);
                  //重新放入到队列中
                  sb.replace(index,sb.length(),String.valueOf(sum));
              }
          }
          //以上的步骤实行之后,没有左右括号了,求字符串+-号之间元素的运算结果,返回结果
          return  sumCount(sb,-1);
    }
    //此方法就是求括号之间的和
    public  int sumCount(StringBuilder sb,int index)
    {
        //计一个变量,用来求括号两者之间的和
        int sum=0;
        //设立标志位,标明(右边的第一个元素,有可能是-,也有可能是数字
        //设置的目的是记录当前运算符号(+-)之前的一个运算符号(+-)
        int flag=index+1;
        //因为标志位有可能是两种情况,所以我们从标志位的后一位开始,看是否是+-号
        for(int i=flag+1;i<sb.length();i++)
        {
            //当遇到+-号的时候,我们开始要进行一些运算,具体的就是+代表之前的运算结果加上下一个运算符号之前的数字,-则是减去
            if(sb.charAt(i)=='+' || sb.charAt(i)=='-' )
            {
                //当我们第一次遇到(运算符号的时候)
                //变量sum记为第一个运算符号之前整数元素的值,同时标志位发生改变,记录下这个当前运算符号所在的位置
                if(flag==index+1)
                {
                    sum=Integer.valueOf(sb.substring(flag,i));
                    flag=i+1;
                }
                //当不是第一次遇到运算符号的时候
                //通过标志位,判断上一个符号是加运算还是减运算,计算当前运算符号之前各个整数的运算结果,放入到sum中
                else
                {
                    if(sb.charAt(flag-1)=='+')
                    {
                        //如果计算的结果为负数 没有 + -1 这种情况,此时应该是 - 1 我们将+ 去掉,跳过,重新运算,下同。
                        if(sb.charAt(flag)=='-') {
                            sb.replace(flag - 1, flag + 1, "-");
                            continue;
                        }
                        sum+=Integer.valueOf(sb.substring(flag,i));
                        flag=i+1;
                    }
                    else if(sb.charAt(flag-1)=='-')
                    {
                        if(sb.charAt(flag)=='-'){
                            sb.replace(flag-1,flag+1,"+");
                            continue;
                        }
                        sum-=Integer.valueOf(sb.substring(flag,i));
                        flag=i+1;
                    }

                }

            }

        }
        //如果标志位没有改变,那就表明传递的参数是"(546665"或者“465646”这种形式的,直接返回结果
        if(flag==index+1)
        {
            if(index!=-1 && sb.charAt(index)=='(')
                return  Integer.valueOf(sb.substring(index+1,sb.length()));
            else
                return Integer.valueOf(sb.toString());
        }
        //当到了结尾,还有一串整数的时候,重复一次上面的运算。
        if(sb.charAt(flag-1)=='+')
        {
            sum+=Integer.valueOf(sb.substring(flag,sb.length()));

        }
        if(sb.charAt(flag-1)=='-')
        {
            sum-=Integer.valueOf(sb.substring(flag,sb.length()));

        }
        return sum;
    }

}

效果

info
		解答成功:
		执行耗时:16 ms,击败了40.01% 的Java用户
		内存消耗:40.1 MB,击败了32.00% 的Java用户
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值