227-m-Basic Calculator II

四则运算。真的只是四则而已,没有要求括号只有加减乘除,因此还算是简单的,难点可能就在对乘除的处理上。最开始写的是将操作数和操作符全部分别提取到2个数组中,再一个个出栈运算,发现不好写,因为数组是静态栈消不掉元素。后来还是在操作数入栈的时候就做处理,如果是乘除的直接算出结果再入栈,最后对2个栈进行加减法就可以了。本题写的逻辑一般,空间还占用了不小(因为用了2个数组做栈,用例中有上万个元素的例子,所以数组我设得很大),ac花了12ms。

睡了个午觉觉得空间占用太大而且循环了2次(2n时间复杂度),决定修改一下:在元素入栈时,当操作符大于等于2时直接计算首2个元素的结果并保存在a[0]中(因为逻辑中先对乘除做了处理,所以操作符大于等于2时可以保证一定是加减),所以空间立马将为3,而入栈即计算所以一遍循环就够,果然ac时只花了8ms。

发现c的程序运行确实比c++快很多,一些小题目用c++写ac时都是数百ms起步,而c一般10ms就差不多了。

如下,大空间的已经注释掉,用的是入栈即计算逻辑:

int calculate(char* s) {
    int result = 0;
    int n = 4;
    int numstack[n];
    char operastack[n];
    memset(numstack, 0, sizeof(int) * n);
    memset(operastack, 0, sizeof(char) * n);
    char *sp = s;
    char *nums = "0123456789";
    char *opera = "+-*/";
    char *powerdivide = "*/";
    char *plusminus = "+-";
    
    int num = 0;
    int indexo = 0, indexn = 0;
    while (*sp != '\0') { //将操作数和操作符分别入栈
        if (strchr(nums, *sp)) {
            while (strchr(nums, *sp) && *sp != '\0') {
                num = num * 10 + *sp - '0';
                sp++;
            }
            numstack[indexn] = num;
            indexn++;
            if (indexo > 0 && strchr(powerdivide, operastack[indexo - 1])) { //如果是乘除则实时计算并结果入栈同时消掉符号和操作数
                int temp = 0;
                if (operastack[indexo - 1] == '*')
                    temp = numstack[indexn - 2] * numstack[indexn - 1];
                else
                    temp = numstack[indexn - 2] / numstack[indexn - 1];
                numstack[indexn - 2] = temp;
                indexn--;
                indexo--;
            }
            if (indexo > 1) { //在操作数大于等于3时直接计算头2个的结果,可以大幅降低空间复杂度,并降低时间复杂度
                int temp = 0;
                if (operastack[0] == '+')
                    temp = numstack[0] + numstack[1];
                else if (operastack[0] == '-')
                    temp = numstack[0] - numstack[1];
                numstack[0] = temp;
                numstack[1] = numstack[2];
                indexn--;
                operastack[0] = operastack[1];
                indexo--;
            }
        }
        if (*sp == '\0')
            break;
        if (strchr(opera, *sp)) {
            operastack[indexo] = *sp;
            num = 0;
            indexo++;
        }
        sp++;
    }
//    for (int i = 0; i < indexo; i++) { //最后归结为加减运算
//        if (operastack[i] == '+') {
//            result = numstack[i] + numstack[i + 1];
//            numstack[i + 1] = result;
//        }
//        else if (operastack[i] == '-') {
//            result = numstack[i] - numstack[i + 1];
//            numstack[i + 1] = result;
//        }
//    }
    if (operastack[0] == '+') { //由于入栈时直接计算过结果并保存在首元素,因此只需计算首2个元素即可
        result = numstack[0] + numstack[1];
        numstack[0] = result;
    }
    else if (operastack[0] == '-') {
        result = numstack[0] - numstack[1];
        numstack[0] = result;
    }

//    if (indexo < 1) //如果没有操作符,则结果等于首个操作数
    result = numstack[0];
    
    return result;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值