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;
}
相关推荐
小白程序员成长日记1 小时前
2025.12.02 力扣每日一题
数据结构·算法·leetcode
永远都不秃头的程序员(互关)1 小时前
在vscodeC语言多文件编译实战指南
c语言·数据结构·算法
橘颂TA1 小时前
【Linux】System V 通信——共享内存
linux·运维·服务器·c++
天赐学c语言1 小时前
Linux - 网络基础概念
linux·服务器·网络·socket
程序员果子1 小时前
零拷贝:程序性能加速的终极奥秘
linux·运维·nginx·macos·缓存·centos
吃着火锅x唱着歌2 小时前
LeetCode 3583.统计特殊三元组
算法·leetcode·职场和发展
请叫我7plus2 小时前
用QEMU进行嵌入式Linux开发
linux·驱动开发·嵌入式硬件
檀越剑指大厂2 小时前
【Linux系列】Linux中的复制与迁移
linux·运维·服务器
Keine Zeit2 小时前
虚拟机Linux(Ubuntu)忘记登录密码
linux·运维·ubuntu