Leetcode 每日一题C 语言版 -- 234 basic calculator

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.

解法

  1. 提取数字,遇到非数字停下,计算当前和
  2. 如果被( 停下,当前值和当前符号入栈
  3. 如果被- 停下,符号取反
  4. 遇到), 出栈, 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;
}
相关推荐
揽星河..25 分钟前
【C语言】分支和循环
c语言·c++·算法
AI_Lab0143 分钟前
宝塔用了两年,有没有必要换成轻量方案?
linux·运维·服务器
by209991 小时前
Linux GDB 调试与 CGDB 使用
linux·运维·服务器·经验分享
星恒随风1 小时前
Linux网络编程:应用层协议究竟是什么?从网络计算器到TCP Socket抽象基类完整实现
linux·网络·笔记·tcp/ip
揽星河..3 小时前
【C语言】猜数字游戏
c语言·算法·游戏
feng_you_ying_li4 小时前
linux之网络层
linux·运维·网络
未来之窗软件服务4 小时前
Linux 运维日志删除的多种方式—东方仙盟
linux·运维·服务器·仙盟创梦ide·东方仙盟
小雉系统4 小时前
BcoreOS实战:用一个升级包,让Rocky Linux跑进Debian服务器
linux·运维·服务器·debian
thethefighter4 小时前
快速预览Word、WPS秒开,支持空格弹窗
linux·word·wps·快速预览·空格弹窗·nhdeepview
用户8351414049495 小时前
把日志和寄存器值喂给AI做故障定位,我的实际问法
linux·ubuntu