Leetcode 每日一题C 语言版 -- 234 basic calculator
日拱一卒,功不唐捐。欢迎诸君评论区打卡同行共勉!!
问题描述
https://leetcode.com/problems/basic-calculator/?envType=study-plan-v2\&envId=top-interview-150
Given a string s representing a valid expression, implement a basic calculator to evaluate it, and return the result of the evaluation.
Note: You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as eval().
Example 1:
Input: s = "1 + 1"
Output: 2
Example 2:
Input: s = " 2-1 + 2 "
Output: 3
Example 3:
Input: s = "(1+(4+5+2)-3)+(6+8)"
Output: 23
Constraints:
1 <= s.length <= 3 * 105
s consists of digits, '+', '-', '(', ')', and ' '.
s represents a valid expression.
'+' is not used as a unary operation (i.e., "+1" and "+(2 + 3)" is invalid).
'-' could be used as a unary operation (i.e., "-1" and "-(2 + 3)" is valid).
There will be no two consecutive operators in the input.
Every number and running calculation will fit in a signed 32-bit integer.
解法
- 提取数字,遇到非数字停下,计算当前和
- 如果被( 停下,当前值和当前符号入栈
- 如果被- 停下,符号取反
- 遇到), 出栈, sum = old_sum + old_sign * sum
c
#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
#define MAX_STACK_DEPTH (16)
struct stack_buffer {
int64_t sum;
int sign;
};
struct stack_t {
int depth;
int max_depth;
struct stack_buffer *buffer;
};
static int stack_init(struct stack_t *stack, int max_depth)
{
stack->buffer = malloc(sizeof(struct stack_t) * max_depth);
stack->max_depth = max_depth;
stack->depth = 0;
return 0;
}
static int stack_expand(struct stack_t *stack)
{
struct stack_buffer *tmp_buffer = NULL;
tmp_buffer = malloc(sizeof(struct stack_buffer) * (stack->max_depth << 1));
memcpy(tmp_buffer, stack->buffer, \
sizeof(struct stack_buffer) *stack->max_depth);
stack->max_depth = stack->max_depth << 1;
free(stack->buffer);
stack->buffer = tmp_buffer;
return 0;
}
static void stack_deinit(struct stack_t *stack)
{
if (!stack)
return;
free(stack->buffer);
stack->buffer = NULL;
stack->max_depth = 0;
stack->depth = 0;
}
static int stack_push(struct stack_t *stack, struct stack_buffer *buffer)
{
if (!stack || !stack->buffer || !buffer)
return -EINVAL;
if (stack->depth == stack->max_depth)
stack_expand(stack);
stack->buffer[stack->depth++] = *buffer;
return 0;
}
static int stack_pop(struct stack_t *stack, struct stack_buffer *buffer)
{
if (!stack || !stack->buffer || !buffer)
return -EINVAL;
if (!stack->depth)
return -ENODATA;
*buffer = stack->buffer[--stack->depth];
return sizeof(*buffer);
}
static struct stack_t stack;
static inline bool is_digital(char c)
{
if (c >= '0' && c <= '9')
return true;
return false;
}
int calculate(char* s) {
int i = 0;
int64_t num = 0;
int64_t sum = 0;
int sign = +1;
struct stack_buffer buffer;
stack_init(&stack, MAX_STACK_DEPTH);
for (i = 0; i < strlen(s); i++) {
if (is_digital(s[i])) {
num = 0;
while (i < strlen(s)) {
if (!is_digital(s[i]))
break;
num = num * 10 + s[i] - '0';
i++;
}
sum += sign * num;
sign = +1;
i--;
} else if (s[i] == '(') {
buffer.sum = sum;
buffer.sign = sign;
sum = 0;
sign = + 1;
stack_push(&stack, &buffer);
} else if (s[i] == ')') {
if (stack_pop(&stack, &buffer) > 0) {
printf("buffer %d %d, sum %d\n",
buffer.sum, buffer.sign, sum);
sum = buffer.sum + buffer.sign * sum;
}
} else if (s[i] == '-') {
sign = -sign;
}
}
stack_deinit(&stack);
return (int)sum;
}