Leetcode 227 Basic Calculator II

**题目:**Implement a basic calculator to evaluate a simple expression string.
The expression string contains only non-negative integers, +, -, *, / operators and empty spaces . The integer division should truncate toward zero.
题目理解: 题目意思很好理解啦!就是写一个字符串表达式值得计算,主要考察的对数据结构— 的使用,考察不同运算符的优先级。当然自己在做这题的时候,有去考虑括号的处理,自己第一遍A的代码就特别长。代码截图如下

int op_cal(int t1,int t2,char ch)
{
    if(ch=='+')
        return t1+t2;
    else if(ch=='-')
        return t1-t2;
    else if(ch=='*')
        return t1*t2;
    else if(ch=='/')
        return t1/t2;
}
int compareop(char ch1,char ch2)//compare the priotity
{
    if(ch1=='(')
        return 0;
    if(ch1=='+')
    {
        return 0;
    }
    if(ch1=='-')
    {
        if(ch2=='+'||ch2=='-')
            return 1;
        else
            return 0;
    }
    if(ch1=='*'||ch1=='/')
        return 1;

}
int calculate(string s1)
{
    vector<char> s;
    for(int j=0;j<s1.size();j++)
    {
        if(s1[j]!=' ')
            s.push_back(s1[j]);
    }
    if(s.size()==0)
        return 0;
    int i=0;
    stack<int> inter;
    stack<char> op; 
    bool brac=false;
    while(i<s.size())
    {
        if(isdigit(s[i]))
        {
            int te=0;
            while(isdigit(s[i])&&i<s.size())
            {
                te =te *10+s[i]-'0';
                i++;
            }
            inter.push(te);
        }
        else
        {
            if(op.size()==0)
                op.push(s[i]);
            else if(s[i]=='(')
                op.push(s[i]);
            else if(s[i]==')')
            {
                while(op.top()!='(')
                {
                    int t1=inter.top();
                    inter.pop();
                    int t2=inter.top();
                    inter.pop();
                    char te=op.top();
                    inter.push(op_cal(t2,t1,te));
                    op.pop();
                }
                op.pop(); //the operation in bracket are completed
            }
            else
            {
                while(op.size()!=0)
                {
                    int temp=compareop(op.top(),s[i]);
                    if(temp==1)
                        {
                            int t1=inter.top();
                            inter.pop();
                            int t2=inter.top();
                            inter.pop();
                            cout<<op_cal(t2,t1,op.top())<<endl;
                            inter.push(op_cal(t2,t1,op.top()));
                            op.pop();
                        }
                    else
                    {

                        break;
                    }
                }
                op.push(s[i]);
            }
            i++;
        }
    }
    while(op.size()!=0)
    {
        int t1=inter.top();
        inter.pop();
        int t2=inter.top();
        inter.pop();
        inter.push(op_cal(t2,t1,op.top()));
        op.pop();
    }
    return inter.top();
}

上面就是自己写的代码,思路很简单,每次先匹配字符,如果是数字,那么就把它丢到一个专门存储数值的栈中,这里需要考虑的就是如果是多位数的时候,要多计算几次。然后接着匹配,如果匹配到的是运算符,就要多考虑一下。对于左括号(题目中不会有括号),那么直接入栈。对于其它运算符,加号,减号,乘号,除法就需要多考虑一些。这里有一个专门存储运算符的栈,每次把匹配到的字符串为运算符的字符串和栈中的运算符进行比较,然后依据情况看是否需要进行运算。这样下去就可以把最后的结果给 算出来。其中比较的过程如下:
设ch1为运算符栈顶,ch2为字符串中匹配的运算符
1、ch1是加法,那么无论ch2是什么运算符,都可以选择放到后面去算。
2、ch1是减法,如果ch2是加法或者减法,那么前面是肯定需要先计算数值呢!
3、ch1是乘法或者除法的时候都选择先算值。
其中计算完一次值后就要把该运算符所在的栈pop一下。然后再把下一个运算符拿出来继续当成ch1再和ch2进行比较,其中比较的过程和上面的相同。
基本上按这样的一个流程,就可以把一个算式最后的值给计算出来。但是自己后面又去看了一下答案发现有更简单的方法。
更简洁的方法:我们思考一个问题,对于运算符为‘-’或者‘+’的时候,我们真的需要考虑那么多吗?对于一个减号的运算符,我们是不是可以把它和后面的一个数组合起来,把它变成它的相反数,丢到堆栈里面。对于加号的运算符就只要把它本身给丢到栈中;如果遇到的是一个乘号或者除号就直接进行计算。最后这些数值都被丢到一个只有整数的栈,然后可以看成是所有数相加把最后的结果算出来。这样做的话比前面的方法简洁很多,忽略掉了比较运算符的优先级。代码也简洁了很多。

    int calculate(string s) 
    {
        if(s.size()==0)
            return 0;
        char op='+';
        int temp=0;
        stack<int> inter;
        for(int i=0;i<s.size();i++)
        {
            if(isdigit(s[i]))
                temp=temp*10+s[i]-'0';
            if(!isdigit(s[i])&&!isspace(s[i])||i==s.size()-1)
            {
                if(op=='-')
                    inter.push(-temp);
                else if(op=='+')
                    inter.push(temp);
                else
                {
                    int t=0;
                    if(op=='*')
                        t=inter.top()*temp;
                    else
                        t=inter.top()/temp;
                    inter.pop();
                    inter.push(t);
                }
                temp=0;
                op=s[i];
            }
        }
        int ans=0;
        while(!inter.empty())
        {
            ans +=inter.top();
            inter.pop();
        }
        return ans;
    }

总结:这题自己想的时候做了好久,不断的处理特殊情况。但是没有想用一种更加简洁的方法去做!还是要多思考啊,多学习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值