开发者社区> 问答> 正文

如何用C语言写一个栈计算器?

如何用C语言写一个栈计算器?要求能实现带小数带括号的四则运算,以及幂运算

展开
收起
算精通 2023-07-16 10:55:10 87 0
2 条回答
写回答
取消 提交回答
  • 要用C语言编写一个栈计算器,可以按照以下步骤进行:

    1. 定义栈的结构和操作:首先,定义一个栈的结构体,并实现相关的操作,如入栈、出栈、查看栈顶元素等。
    // 定义栈结构
    typedef struct {
        int top;
        double stack[MAX_SIZE];
    } Stack;
    
    // 初始化栈
    void init(Stack* stack) {
        stack->top = -1;
    }
    
    // 判断栈是否为空
    int isEmpty(Stack* stack) {
        return stack->top == -1;
    }
    
    // 判断栈是否已满
    int isFull(Stack* stack) {
        return stack->top == MAX_SIZE - 1;
    }
    
    // 入栈
    void push(Stack* stack, double value) {
        if (isFull(stack)) {
            printf("Stack is full\n");
            exit(1);
        }
        stack->stack[++stack->top] = value;
    }
    
    // 出栈
    double pop(Stack* stack) {
        if (isEmpty(stack)) {
            printf("Stack is empty\n");
            exit(1);
        }
        return stack->stack[stack->top--];
    }
    
    // 查看栈顶元素
    double peek(Stack* stack) {
        if (isEmpty(stack)) {
            printf("Stack is empty\n");
            exit(1);
        }
        return stack->stack[stack->top];
    }
    
    1. 编写逆波兰表达式转换函数:逆波兰表达式(后缀表达式)更容易进行计算,因此我们需要将输入的中缀表达式转换为逆波兰表达式。可以使用栈来实现这个转换过程。

    ```c
    // 判断运算符的优先级
    int getPriority(char c) {
    if (c == '^') {
    return 3; // 指数运算符(幂)
    } else if (c == '*' || c == '/') {
    return 2; // 乘法和除法运算符
    } else if (c == '+' || c == '-') {
    return 1; // 加法和减法运算符
    } else {
    return 0; // 数字或其他非运算符
    }
    }

    // 将中缀表达式转换为逆波兰表达式
    void infixToPostfix(char infix, char postfix) {
    Stack stack;
    init(&stack);

    int i = 0; // 中缀表达式索引
    int j = 0; // 逆波兰表达式索引
    
    while (infix[i] != '\0') {
        char ch = infix[i];
    
        // 如果是数字,直接添加到逆波兰表达式
        if (isdigit(ch) || ch == '.') {
            postfix[j++] = ch;
        }
        // 如果是运算符
        else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^' || ch == '(' || ch == ')') {
            // 如果是左括号,直接入栈
            if (ch == '(') {
                push(&stack, ch);
            }
            // 如果是右括号,将栈中的运算符弹出直到遇到左括号
            else if (ch == ')') {
                while (!isEmpty(&stack) && peek(&stack) != '(') {
                    postfix[j++] = pop(&stack);
                }
                if (!isEmpty(&stack) && peek(&stack) == '(') {
                    pop(&stack); // 弹出左括号
                } else {
                    printf("Invalid expression\n");
                    exit(1);
                }
            }
            // 如果是其他运算符,比较优先级后处理
            else {
                while (!isEmpty(&stack) && getPriority(ch) <= getPriority(peek(&stack))) {
                    postfix[j++] = pop(&stack);
                }
                push(&stack, ch);
            }
        }
        i++;
    }
    
    // 将栈中剩余的运算符弹出
    while (!isEmpty(&stack)) {
        if (peek(&stack) == '(') {
            printf("Invalid expression\n");
            exit(1);
        }
        postfix[j++] = pop
    
    2023-07-16 12:43:31
    赞同 展开评论 打赏
  • 北京阿里云ACE会长

    使用C语言实现栈计算器的示例代码。该代码支持带小数、带括号的四则运算和幂运算。该代码使用栈数据结构来实现计算器功能。

    c
    Copy

    include

    include

    include

    include

    define MAX_STACK_SIZE 100 / 栈的最大容量 /

    / 定义栈结构体 /
    typedef struct {
    double items[MAX_STACK_SIZE];
    int top;
    } Stack;

    / 初始化栈 /
    void init_stack(Stack *s) {
    s->top = -1;
    }

    / 判断栈是否为空 /
    int is_empty(Stack *s) {
    return s->top == -1;
    }

    / 判断栈是否已满 /
    int is_full(Stack *s) {
    return s->top == MAX_STACK_SIZE - 1;
    }

    / 将元素压入栈 /
    void push(Stack *s, double value) {
    if (is_full(s)) {
    printf("Stack Overflow\n");
    exit(1);
    }
    s->top++;
    s->items[s->top] = value;
    }

    / 从栈中弹出元素 /
    double pop(Stack *s) {
    if (is_empty(s)) {
    printf("Stack Underflow\n");
    exit(1);
    }
    double value = s->items[s->top];
    s->top--;
    return value;
    }

    / 获取栈顶元素 /
    double peek(Stack *s) {
    if (is_empty(s)) {
    printf("Stack Underflow\n");
    exit(1);
    }
    return s->items[s->top];
    }

    / 判断字符是否为运算符 /
    int is_operator(char ch) {
    return ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^';
    }

    / 获取运算符的优先级 /
    int get_precedence(char ch) {
    switch (ch) {
    case '+':
    case '-':
    return 1;
    case '*':
    case '/':
    return 2;
    case '^':
    return 3;
    default:
    return 0;
    }
    }

    / 执行二元运算 /
    double perform_operation(double num1, double num2, char operator) {
    switch (operator) {
    case '+':
    return num1 + num2;
    case '-':
    return num1 - num2;
    case '':
    return num1
    num2;
    case '/':
    return num1 / num2;
    case '^':
    return pow(num1, num2);
    default:
    return 0.0;
    }
    }

    / 计算表达式 /
    double evaluate_expression(const char expr) {
    Stack operand_stack; /
    操作数栈 /
    Stack operator_stack; /
    运算符栈 */
    init_stack(&operand_stack);
    init_stack(&operator_stack);

    int i = 0;
    while (expr[i] != '\0') {
        /* 如果当前字符是空格,忽略它 */
        if (expr[i] == ' ') {
            i++;
            continue;
        }
    
        /* 如果当前字符是数字或小数点,获取完整的数值并将其推入操作数栈 */
        if (isdigit(expr[i]) || expr[i] == '.') {
            double value = 0.0;
            int decimal_places = 0;
    
            while (isdigit(expr[i]) || expr[i] == '.') {
                if (expr[i] == '.') {
                    decimal_places = 1;
                } else {
                    value = value * 10 + (expr[i] - '0');
                    if (decimal_places > 0) {
                        decimal_places++;
                    }
                }
                i++;
            }
    
            if (decimal_places > 0) {
                value = value / pow(10, decimal_places - 1);
            }
    
            push(&operand_stack, value);
            continue;
        }
    
        /* 如果当前字符是左括号,将其推入运算符栈 */
        if (expr[i] == '(') {
            push(&operator_stack, expr[i]);
            i++;
            continue;
        }
    
        /* 如果当前字符是右括号,从运算符栈中弹出运算符和操作数,执行相应的操作直到遇到左括号 */
        if (expr[i] == ')') {
            while (peek(&operator_stack) != '(') {
                char operator = (char)pop(&operator_stack);
                double num2 = pop(&operand_stack);
                double num1 = pop(&operand_stack);
                double result = perform_operation(double)num1, (double)num2, operator);
                push(&operand_stack, result);
            }
            pop(&operator_stack);
            i++;
            continue;
        }
    
        /* 如果当前字符是运算符,将其推入运算符栈。如果当前运算符的优先级低于或等于栈顶运算符的优先级,则从运算符栈中弹出运算符和操作数,执行相应的操作 */
        if (is_operator(expr[i])) {
            while (!is_empty(&operator_stack) && get_precedence(expr[i]) <= get_precedence(peek(&operator_stack))) {
                char operator = (char)pop(&operator_stack);
                double num2 = pop(&operand_stack);
                double num1 = pop(&operand_stack);
                double result = perform_operation((double)num1, (double)num2, operator);
                push(&operand_stack, result);
            }
            push(&operator_stack, expr[i]);
            i++;
            continue;
        }
    
        /* 如果表达式中存在未知字符,则无法计算 */
        printf("Invalid Character Found: %c\n", expr[i]);
        exit(1);
    }
    
    /* 如果表达式已经扫描完但是运算符栈不为空,则从运算符栈中弹出运算符和操作数,执行相应的操作 */
    while (!is_empty(&operator_stack)) {
        char operator = (char)pop(&operator_stack);
        double num2 = pop(&operand_stack);
        double num1 = pop(&operand_stack);
        double result = perform_operation((double)num1, (double)num2, operator);
        push(&operand_stack, result);
    }
    
    /* 最后,操作数栈中的唯一元素即为结果 */
    return pop(&operand_stack);
    

    }

    int main() {
    char expr[MAX_STACK_SIZE];
    printf("Enter an expression: ");
    fgets(expr, MAX_STACK_SIZE, stdin);
    double result = evaluate_expression(expr);
    printf("Result: %.2lf\n", result);
    return 0;
    }
    代码中的主要思路是将表达式中的数字和运算符分别推入操作数栈和运算符栈,并在需要时从栈中弹出元素进行计算。该代码可以读入带括号、带小数的四则运算表达式,支持幂运算,能输出结果精确到小数点后两位。

    2023-07-16 11:02:42
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载