“ 忠诚、笃学、严谨、守纪 ”

点击任意处进入

数据结构实验二

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

#define MAXSIZE 100

// 字符栈:存储 运算符/括号
typedef struct {
    char data[MAXSIZE];
    int top;
} CharStack;

// 数值栈:存储 浮点数
typedef struct {
    double data[MAXSIZE];  // 改为 double
    int top;
} NumStack;

// ======================== 字符栈操作 ========================
void InitCharStack(CharStack *s) {
    s->top = -1;
    memset(s->data, 0, sizeof(s->data));
}

int IsCharEmpty(CharStack *s) {
    return s->top == -1;
}

int PushChar(CharStack *s, char ch) {
    if (s->top == MAXSIZE - 1) return 0;
    s->data[++s->top] = ch;
    return 1;
}

int PopChar(CharStack *s, char *ch) {
    if (IsCharEmpty(s)) return 0;
    *ch = s->data[s->top--];
    return 1;
}

char GetTopChar(CharStack *s) {
    if (IsCharEmpty(s)) return '#';
    return s->data[s->top];
}

// ======================== 数值栈操作(浮点版) ========================
void InitNumStack(NumStack *s) {
    s->top = -1;
    memset(s->data, 0, sizeof(s->data));
}

int PushNum(NumStack *s, double num) {  // double
    if (s->top == MAXSIZE - 1) return 0;
    s->data[++s->top] = num;
    return 1;
}

int PopNum(NumStack *s, double *num) {  // double
    if (s->top == -1) return 0;
    *num = s->data[s->top--];
    return 1;
}

double GetTopNum(NumStack *s) {  // double
    if (s->top == -1) return 0;
    return s->data[s->top];
}

// ======================== 工具函数 ========================
int IsOperator(char ch) {
    return ch == '+' || ch == '-' || ch == '*' || ch == '/';
}

int IsNumber(char ch) {
    return (ch >= '0' && ch <= '9') || ch == '.';  // 支持小数点
}

int GetPriority(char ch) {
    if (ch == '*' || ch == '/') return 2;
    if (ch == '+' || ch == '-') return 1;
    return 0;
}

// 浮点运算
double Operate(double a, double b, char op) {
    switch (op) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/':
            if (b == 0) {
                printf("错误:除数不能为0!\n");
                exit(1);
            }
            return a / b;
        default: return 0;
    }
}

// ======================== 中缀转后缀 ========================
void InfixToPostfix(const char *infix, char *postfix) {
    CharStack s;
    InitCharStack(&s);
    int i = 0, j = 0;
    char ch, topOp;
    memset(postfix, 0, MAXSIZE);

    while (infix[i] != '\0' && i < MAXSIZE - 1) {
        ch = infix[i];

        if (IsNumber(ch)) {
            while (IsNumber(infix[i])) {
                postfix[j++] = infix[i++];
            }
            postfix[j++] = ' ';
        } else if (ch == '(') {
            PushChar(&s, ch);
            i++;
        } else if (ch == ')') {
            while (!IsCharEmpty(&s) && GetTopChar(&s) != '(') {
                PopChar(&s, &topOp);
                postfix[j++] = topOp;
                postfix[j++] = ' ';
            }
            PopChar(&s, &topOp);
            i++;
        } else if (IsOperator(ch)) {
            while (!IsCharEmpty(&s) && GetPriority(GetTopChar(&s)) >= GetPriority(ch)) {
                PopChar(&s, &topOp);
                postfix[j++] = topOp;
                postfix[j++] = ' ';
            }
            PushChar(&s, ch);
            i++;
        } else {
            i++;
        }
    }

    while (!IsCharEmpty(&s)) {
        PopChar(&s, &topOp);
        postfix[j++] = topOp;
        postfix[j++] = ' ';
    }
    postfix[j] = '\0';
}

// ======================== 后缀表达式求值 ========================
double CalculatePostfix(const char *postfix) {
    NumStack s;
    InitNumStack(&s);
    int i = 0;
    char ch;
    double a, b;

    while (postfix[i] != '\0' && i < MAXSIZE - 1) {
        ch = postfix[i];

        if (IsNumber(ch)) {
            double num = 0;
            int dot = 0;
            double div = 10;

            while (IsNumber(postfix[i])) {
                if (postfix[i] == '.') {
                    dot = 1;
                } else {
                    if (!dot) {
                        num = num * 10 + (postfix[i] - '0');
                    } else {
                        num = num + (postfix[i] - '0') / div;
                        div *= 10;
                    }
                }
                i++;
            }
            PushNum(&s, num);
        } else if (IsOperator(ch)) {
            PopNum(&s, &b);
            PopNum(&s, &a);
            PushNum(&s, Operate(a, b, ch));
            i++;
        } else {
            i++;
        }
    }
    return GetTopNum(&s);
}

// ======================== 菜单 ========================
void Menu() {
    printf("==================== 四则运算表达式求值 ====================\n");
    printf("  1. 计算表达式结果\n");
    printf("  0. 退出程序\n");
    printf("==================================================================\n");
    printf("请输入功能编号:");
}

// ======================== 主函数 ========================
int main() {
    int choice;
    char infix[MAXSIZE] = {0};
    char postfix[MAXSIZE] = {0};

    while (1) {
        Menu();
        if (scanf("%d", &choice) != 1) {
            printf("输入错误!\n\n");
            while (getchar() != '\n');
            continue;
        }
        getchar();

        switch (choice) {
            case 1:
                printf("\n请输入算术表达式(支持小数 + - * / ( ),如:(3.5+2.5)*2-6/2.5):\n");
                fgets(infix, MAXSIZE, stdin);
                infix[strcspn(infix, "\n")] = '\0';

                InfixToPostfix(infix, postfix);
                printf("后缀表达式:%s\n", postfix);

                double res = CalculatePostfix(postfix);
                printf("计算结果:%.2f\n\n", res);  // 保留两位小数
                break;

            case 0:
                printf("程序已退出!\n");
                return 0;

            default:
                printf("输入错误,请重新选择!\n\n");
        }
    }
}
posted @ 2026-06-02 15:20  alonep  阅读(9)  评论(0)    收藏  举报