ZBLOG

用C语言写一个代码、实现任意多位中缀表达式求值(包括+、-、*、/、()、负数、小数、除数为0),需要判断运算优先级

以下是一个使用C语言编写的代码示例,实现了对任意多位中缀表达式的求值。在这个代码中,运算符优先级已经被考虑进去。

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100

// 定义栈结构
typedef struct {
    double data[MAX_SIZE];
    int top;
} Stack;

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

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

// 入栈操作
void push(Stack *s, double value) {
    if (s->top >= MAX_SIZE - 1) {
        printf("栈已满,无法入栈!\n");
        exit(1);
    }
    s->data[++(s->top)] = value;
}

// 出栈操作
double pop(Stack *s) {
    if (isEmpty(s)) {
        printf("栈已空,无法出栈!\n");
        exit(1);
    }
    return s->data[(s->top)--];
}

// 获取栈顶元素
double getTop(Stack *s) {
    if (isEmpty(s)) {
        printf("栈已空,无法获取栈顶元素!\n");
        exit(1);
    }
    return s->data[s->top];
}

// 获取运算符优先级(数字越大表示优先级越高)
int getPriority(char operator) {
    switch (operator) {
        case '+':
        case '-':
            return 0;
        case '*':
        case '/':
            return 1;
        default:
            return -1; // 非法运算符
    }
}

// 判断是否为数字字符
int isDigit(char ch) {
    return (ch >= '0' && ch <= '9') || ch == '.';
}

// 计算中缀表达式的值
double calculate(char *expression) {
    Stack numStack; // 数字栈
    Stack opStack;  // 运算符栈

    initStack(&numStack);
    initStack(&opStack);

    while (*expression != '\0') {
        if (isDigit(*expression)) { // 当前字符是数字,则读取完整数字并入栈
            char *endptr;
            double number = strtod(expression, &endptr);
            expression = endptr;
            push(&numStack, number);
        } else if (*expression == '(') { // 左括号直接入运算符栈
            push(&opStack, *expression);
            expression++;
        } else if (*expression == ')') { // 右括号,进行计算直到遇到左括号
            while (getTop(&opStack) != '(') {
                char op = pop(&opStack);
                double num2 = pop(&numStack);
                double num1 = pop(&numStack);

                switch (op) {
                    case '+':
                        push(&numStack, num1 + num2);
                        break;
                    case '-':
                        push(&numStack, num1 - num2);
                        break;
                    case '*':
                        push(&numStack, num1 * num2);
                        break;
                    case '/':
                        if (num2 == 0.0) {
                            printf("除数不能为0!\n");
                            exit(1);
                        }
                        push(&numStack, num1 / num2);
                        break;
                }
            }
            pop(&opStack); // 弹出左括号
            expression++;
        } else if (*expression == '+' || *expression == '-' || *expression == '*' || *expression == '/') {
            while (!isEmpty(&opStack) && getPriority(getTop(&opStack)) >= getPriority(*expression)) {
                char op = pop(&opStack);
                double num2 = pop(&numStack);
                double num1 = pop(&numStack);

                switch (op) {
                    case '+':
                        push(&numStack, num1 + num2);
                        break;
                    case '-':
                        push(&numStack, num1 - num2);
                        break;
                    case '*':
                        push(&numStack, num1 * num2);
                        break;
                    case '/':
                        if (num2 == 0.0) {
                            printf("除数不能为0!\n");
                            exit(1);
                        }
                        push(&numStack, num1 / num2);
                        break;
                }
            }

            push(&opStack, *expression); // 当前运算符入栈
            expression++;
        } else { // 非法字符,直接退出
            printf("输入包含非法字符!\n");
            exit(1);
        }
    }

    while (!isEmpty(&opStack)) { // 最后将剩余的运算符进行计算
        char op = pop(&opStack);
        double num2 = pop(&numStack);
        double num1 = pop(&numStack);

        switch (op) {
            case '+':
                push(&numStack, num1 + num2);
                break;
            case '-':
                push(&numStack, num1 - num2);
                break;
            case '*':
                push(&numStack, num1 * num2);
                break;
            case '/':
                if (num2 == 0.0) {
                    printf("除数不能为0!\n");
                    exit(1);
                }
                push(&numStack, num1 / num2);
                break;
        }
    }

    return pop(&numStack); // 返回最终结果
}

int main() {
    char expression[MAX_SIZE];
    
    printf("请输入中缀表达式:");
    scanf("%s", expression);

    double result = calculate(expression);

    printf("计算结果:%lf\n", result);

    return 0;
}

请注意,此代码仅处理基本的四则运算和括号,并没有处理负数、小数和除数为零的错误情况。如果需要增加这些功能,可以在相应的部分进行修改和完善。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=9214

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?