四则运算。真的只是四则而已,没有要求括号只有加减乘除,因此还算是简单的,难点可能就在对乘除的处理上。最开始写的是将操作数和操作符全部分别提取到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;
}