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;
}
相关推荐
leaves falling13 分钟前
c语言-扫雷游戏
c语言·单片机·游戏
梁洪飞1 小时前
clk学习
linux·arm开发·嵌入式硬件·arm
一起养小猫1 小时前
LeetCode100天Day14-轮转数组与买卖股票最佳时机
算法·leetcode·职场和发展
~光~~1 小时前
【嵌入式linux驱动——点亮led】基于鲁班猫4 rk3588s
linux·点灯·嵌入式linux驱动
至为芯1 小时前
IP6537至为芯支持双C口快充输出的45W降压SOC芯片
c语言·开发语言
yuanmenghao2 小时前
车载Linux 系统问题定位方法论与实战系列 - 车载 Linux 平台问题定位规范
linux·运维·服务器·网络·c++
程序员-King.3 小时前
day143—递归—对称二叉树(LeetCode-101)
数据结构·算法·leetcode·二叉树·递归
qq_589568103 小时前
centos6.8镜像源yum install不成功,无法通过镜像源下载的解决方式
linux·运维·centos
weixin_516023074 小时前
linux下fcitx5拼音的安装
linux·运维·服务器
hunter14504 小时前
Linux 进程与计划任务
linux·运维·服务器