计算表达式的值(转为后缀表达式)

```
#include<stdio.h>
#include<stdlib.h>
#define new(x) (x*)malloc(sizeof(x))//便于申请动态存储空间
#define com(x) x>='0'&&x<='9'//便于判断是不是数字
const int N = 100;
typedef struct stack {//定义栈sta
    char zf;
    struct stack* next;
} sta;
typedef struct queue {//定义队列结点que
    char data;
    struct queue* next;
} que;
struct QUEUE {//队列的头尾指针
    que* begin;
    que* end;
} Q;
char a[N],*s=a;
sta* T;
void Init() {
    T = NULL;//T是栈,Q是队列
    Q.begin = Q.end = NULL;
}
void T_push(char ch) {//栈头插法
    sta* p = new(sta);
    p->zf = ch;;
    p->next = T;
    T = p;
}
char T_top() {//获取栈顶元素但不出栈
    return T->zf;
}
void T_pop() {//将栈顶元素出栈
    sta* p = T;
    T = T->next;
    free(p);
}
int T_IsEmpty() {//判栈空
    return T == NULL;
}
void Q_push(char x) {//尾插法创建队列
    que* p = new(que);
    if (Q.begin == NULL) {
        Q.begin = new(que);
        p->data = x;
        Q.begin = p;
        Q.begin->next = Q.end;
        Q.end = Q.begin;
    }
    else {
        p->data = x;
        Q.end->next = p;
        Q.end = p;
    }
    Q.end->next = NULL;
}
char Q_front() {//获取队首元素但不出队
    return Q.begin->data;
}
void Q_pop() {//将队首元素出队
    que* p = Q.begin;
    Q.begin = p->next;
    free(p);
}
int Q_IsEmpty() {//判队空
    return Q.begin == NULL;
}
void Deal() {//将中缀表达式转化为后缀表达式存储在队列Q中,T只是一个临时的运算符栈
    while (*s != '\0') {
        if (com(*s)) {//如果出现了数字那就将其读完并输出到Q中,并在该数后面加个空格,防止出现多位数的情况
            while (com(*s)) {
                Q_push(*s);
                s++;
            }
            Q_push(' ');
            continue;
        }
        if (T_IsEmpty()) {//如果运算符栈是空的,那就直接将运算符入栈
            T_push(*s);
            s++;
            continue;
        }
        if (*s == '+' || *s == '-') {//'+'和'-'只有当栈顶元素是'('或者栈空时才能入栈
            if (T_top() == '(')//栈顶元素是'(',直接入栈
                T_push(*s);
            else {
                while (!T_IsEmpty()&& T_top() != '(') {//栈顶元素不是'(’,那就一直出栈输出到Q中,直到栈顶元素是'('或者栈空
                    Q_push(T_top());
                    T_pop();
                }
                T_push(*s);
            }
            s++;
            continue;
        }
        if (*s == '*' || *s == '/') {//'*'和'/'只要栈顶元素不是'*'或'/'即可入栈
            if (T_top() != '*' && T_top() != '/')
                T_push(*s);
            else {
                while (T_IsEmpty()||T_top() == '*' || T_top() == '/') {//如果栈顶元素不满足条件的话,那就一直出栈输出到Q中,直到满足入栈情况
                    Q_push(T_top());
                    T_pop();
                }
                T_push(*s);
            }
            s++;
        }
        if (*s == '(') {//入栈时'('优先级最高,直接入栈
            T_push(*s);
            s++;
            continue;
        }
        if (*s == ')') {//碰到')'的话那就一直出栈输出到Q中,直到与之匹配的第一个'('
            while (T_top() != '(') {
                Q_push(T_top());
                T_pop();
            }
            T_pop();
            s++;
        }
    }
    while (!T_IsEmpty()) {//如果最后运算符栈不为空,那就把剩下的运算符一直出栈输出到Q中,直到栈空
        Q_push(T_top());
        T_pop();
    }
}
float Getnum() {//将数字字符串转换成数
    float sum = 0;
    while (com(Q_front())) {
        sum = sum * 10 +( Q_front()-'0');
        Q_pop();
    }
    return sum;
}
int i = -1;//离当前运算符最近的数的下标
float num[N];//存储运算数
float Count(char ch) {//根据ch计算num中最近两个数的结果
    float x;
    switch (ch) {
    case '+':x = num[i - 1] + num[i];
        break;
    case '-':x = num[i - 1] - num[i];
        break;
    case '*':x = num[i - 1] * num[i];
        break;
    case '/':x = num[i - 1] / num[i];
        break;
    }
    return x;
}
float Result() {//计算转换成后缀表达式的值
    while (!Q_IsEmpty()) {
        if (com(Q_front())) {
            num[++i] = Getnum();
            Q_pop();
            continue;
        }
        else{
            num[i-1]=Count(Q_front());
            Q_pop();
            i--;
        }
    }
    return num[0];
}
int main() {
    printf("请输入表达式:\n");
    scanf("%s", a);
    Deal();
    printf("改变后的后缀表达式为:\n");
    que* p = Q.begin;
    while (p) {
        if(p->data!=' ')printf("%c", p->data);
        p = p->next;
    }
    printf("\n");
    printf("该表达式的值为:%.2f", Result());
    return 0;
}

```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值