题意:
实现一个基本的计算器来计算一个简单的字符串表达式 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用户