数据结构|C语言实现中缀表达式转后缀表达式及其计算

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/* 定义符号栈 */
typedef struct CstackNode {
    char data;
    struct CstackNode *next;
} *CStack;
bool CInitStack(CStack *S);
bool CIsEmpty(CStack S);
bool CPush(CStack *S, char e);
bool CPop(CStack *S, char *e);
bool CGetTop(CStack S, char *e);

/* 定义数字栈 */
typedef struct NstackNode {
    int data;
    struct NstackNode *next;
} *NStack;
bool NInitStack(NStack *S);
bool NIsEmpty(NStack S);
bool NPush(NStack *S, int e);
bool NPop(NStack *S, int *e);
bool NGetTop(NStack S, int *e);

int getLevel(char c);        //确定符号种类和优先级
bool check(char *s);         //检查中缀表达式是否合法
char *transform(char *s);    //将中缀表达式转换成后缀表达式
int calculate(char *s);      //计算合法的后缀表达式


int main(void) {
    char *s1 = "((15/(7-(1+1)))*(3))-(2+(1+(1)))";
    char *s2 = "1+2-3*4/2+6";
    char *result = transform(s2);
    if (result) {
        puts(result);
        printf("%d", calculate(result));
    }

}

int getLevel(char c) {
    if ('0' <= c && c <= '9') {
        return 0;
    } else {
        switch (c) {
            case '+': case '-':
                return 1;
                break;
            case '*': case '/':
                return 2;
                break;
            case '(': case ')':
                return 3;
            default:
                return -1;
                break;
        }
    }
}
bool check(char *s) {
    if (s == NULL) {
        printf("非法:输入字符串指针为空!");
        return false;
    } else {
        CStack S;
        CInitStack(&S);
        char e;
        for (int i = 0;s[i] != 0;i++) {
            if (getLevel(s[i]) == -1) {
                printf("非法:字符串含有非法字符!");
                return false;
            } else if (s[i] == '(') {
                CPush(&S, s[i]);
            } else if (s[i] == ')') {
                if (!CPop(&S, &e)) {
                    printf("非法:括号不匹配!");
                    return false;
                }
            }
        }
        if (CIsEmpty(S)) {
            return true;
        } else {
            while (CPop(&S, &e));//避免造成内存泄露,销毁栈并返回false;
            return false;
        }
    }
}
char *transform(char *s) {
    if (check(s)) {
        //计算输入的长度,并确定输出的长度
        int length = 0;
        while (s[length]) {
            length++;
        }
        length *= 2;
        //根据长度初始化result,p为当前待插入索引
        char *result = malloc((length + 1) * sizeof(char));
        for (int i = 0;i <= length;i++) {
            result[i] = 0;
        }
        int p = 0;
        //定义栈,当前元素等级level和栈顶元素top
        CStack S;
        CInitStack(&S);
        int level;
        char top;
        //对输入字符逐个遍历
        for (int i = 0;s[i];i++) {
            //获取level
            switch (level = getLevel(s[i])) {
                case 0:
                    result[p++] = s[i];
                    break;
                    //对于符号,判断如下
                default:
                    if (s[i] == '(') {//左括号直接入栈
                        CPush(&S, s[i]);
                    } else if (s[i] == ')') {//右括号逐个pop,并存入result,直至左括号出现
                        CPop(&S, &top);
                        while (top != '(') {
                            result[p++] = ' ';
                            result[p++] = top;
                            CPop(&S, &top);
                        }
                    } else {//非括号清空下,首先加入空格
                        result[p++] = ' ';
                        if (!CGetTop(S, &top) || top == '(') {//若栈空或栈顶为左括号,符号直接入栈
                            CPush(&S, s[i]);
                        } else if (level == getLevel(top)) {//非栈空非栈顶为左括号的情况下,比较优先级,优先级相等则先pop,再push
                            CPop(&S, &top);
                            result[p++] = top;
                            result[p++] = ' ';
                            CPush(&S, s[i]);
                        } else if (level > getLevel(top)) {//优先级较高则push
                            CPush(&S, s[i]);
                        } else if (level < getLevel(top)) {//优先级较低则一直pop,直到遇到左括号或者栈空再入栈
                            while (top != '(') {
                                CPop(&S, &top);
                                result[p++] = top;
                                result[p++] = ' ';
                                if (!CGetTop(S, &top)) {
                                    break;
                                }
                            }
                            CPush(&S, s[i]);
                        }
                    }
            }
        }
        //将栈内剩余清空
        while (CPop(&S, &top)) {
            result[p++] = ' ';
            result[p++] = top;
        }
        return result;
    } else {
        return NULL;
    }
}
int calculate(char *s) {
    int p = 0;
    int num;  //读取的数字
    int num1;  //操作数1
    int num2;  //操作数2
    NStack S;
    NInitStack(&S);
    while (s[p] != 0) {
        //如果是数字,压入栈中;
        if (getLevel(s[p]) == 0) {
            num = 0;
            while (s[p] != ' ') {
                num *= 10;
                num += (s[p++] - '0');
            }
            p++;
            NPush(&S, num);
        } else {//如果不是数字,做运算,结果入栈
            NPop(&S, &num2);
            NPop(&S, &num1);
            switch (s[p++]) {
                case '+':
                    NPush(&S, num1 + num2);
                    break;
                case '-':
                    NPush(&S, num1 - num2);
                    break;
                case '*':
                    NPush(&S, num1 * num2);
                    break;
                case '/':
                    NPush(&S, num1 / num2);
                    break;
                default:
                    break;
            }
            if (s[p] != 0) {
                p++;
            }
        }
    }
    int result;
    NPop(&S, &result);
    return result;
}

/* 初始化栈 */
bool CInitStack(CStack *S) {
    if (S == NULL) {
        return false;
    } else {
        *S = NULL;
        return true;
    }
}
/* 判空 */
bool CIsEmpty(CStack S) {
    return S == NULL;
}
/* 入栈 */
bool CPush(CStack *S, char e) {
    if (S == NULL) {
        return false;
    } else {
        struct CstackNode *new = malloc(sizeof(struct CstackNode));
        new->data = e;
        new->next = (*S);
        (*S) = new;
        return true;
    }
}
/* 出栈 */
bool CPop(CStack *S, char *e) {
    if (S == NULL || (*S) == NULL) {
        return false;
    } else {
        *e = (*S)->data;
        (*S) = (*S)->next;
        return true;
    }
}
/* 获取栈顶元素 */
bool CGetTop(CStack S, char *e) {
    if (CIsEmpty(S)) {
        return false;
    } else {
        *e = S->data;
        return true;
    }
}

/* 初始化栈 */
bool NInitStack(NStack *S) {
    if (S == NULL) {
        return false;
    } else {
        *S = NULL;
        return true;
    }
}
/* 判空 */
bool NIsEmpty(NStack S) {
    return S == NULL;
}
/* 入栈 */
bool NPush(NStack *S, int e) {
    if (S == NULL) {
        return false;
    } else {
        struct NstackNode *new = malloc(sizeof(struct NstackNode));
        new->data = e;
        new->next = (*S);
        (*S) = new;
        return true;
    }
}
/* 出栈 */
bool NPop(NStack *S, int *e) {
    if (S == NULL || (*S) == NULL) {
        return false;
    } else {
        *e = (*S)->data;
        (*S) = (*S)->next;
        return true;
    }
}
/* 获取栈顶元素 */
bool NGetTop(NStack S, int *e) {
    if (NIsEmpty(S)) {
        return false;
    } else {
        *e = S->data;
        return true;
    }
}

main函数:

运行结果:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值