计算表达式-将中缀表达式转换为后缀表达式后计算

该博客介绍了如何通过将中缀表达式转换为后缀表达式来方便计算。首先,定义后缀表达式的概念,然后详细阐述了将中缀表达式转换为后缀表达式的步骤,包括如何处理运算符的优先级。接着,提供了C语言实现的计算后缀表达式的方法,包括创建栈、入栈、出栈等操作。最后,给出一个简单的测试案例,演示了整个计算过程。
摘要由CSDN通过智能技术生成

为方便实现计算中缀表达式,我们采用先将中缀表达式转换成后缀表达式,再计算后缀表达式的方式。(如果不会转换,请转http://t.csdn.cn/96UFw

后缀表达式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则)

由于后缀表达式的运算符在两个操作数的后面,那么计算机在解析后缀表达式的时候,只需要从左向右扫描,也就是只需要向前扫描,而不用回头扫描,遇到运算符就将运算符放在前面两个操作符的中间(这里先不考虑乘方类似的单目运算),一直运算到最右边的运算符,那么就得出运算结果了。

要实现对后缀表达式的求值:对整个字符串进行遍①

①将字符串型的数字转换为整型(或者浮点型)。

②遇到数字直接入栈;

③遇到运算符(~),则将栈顶的两个数字出栈,并将b~a的指压入栈中。

#include <stdio.h>
#include <string.h>
#include<stdlib.h>
#define MAX 100
typedef struct SNode* Stack;
struct SNode {
    int data;
    Stack next;
};
//初始化空栈 
Stack Init() {
    Stack s = (Stack)malloc(sizeof(SNode*));
    s->next = NULL;
    return s;
}
//创建新结点
Stack creat_node(int x) {
    Stack s = (Stack)malloc(sizeof(SNode*));
    s->data = x;
    s->next = NULL;
    return s;
}
//判断栈空
int Empty(Stack Ptrs) {
    return Ptrs->next == NULL;
}
//入栈
void Push(Stack Ptrs, int x) {
    Stack s = creat_node(x);
    s->next = Ptrs->next;
    Ptrs->next = s;
}
//出栈
int Pop(Stack Ptrs) {
    if (Empty(Ptrs)) {
        printf("堆栈为空");return 0;
    }
    else {
        int t;
        Stack temp = Ptrs->next;
        Ptrs->next = temp->next;
        t = temp->data;
        free(temp);
        return t;
    }
}
//计算后缀表达式
int Calculate(char str[]) {
    Stack Ptrs = Init();
    int i = 0, sum;
    while (str[i] != '\0') {
        if (str[i] >= '0' && str[i] <= '9')//1. 将字符串型的数字转换为整型(或者浮点型)。
        {
            sum = str[i] - '0';
            Push(Ptrs, sum);
        }
        if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')//3. 遇到运算符(#),则将栈中的前两个数字(a和b)出栈,并将b#a的值压入栈中。
        {
            int a = Pop(Ptrs);
            int b = Pop(Ptrs);
            if (str[i] == '+')
                Push(Ptrs, b + a);
            else if (str[i] == '-')
                Push(Ptrs, b - a);
            else if (str[i] == '*')
                Push(Ptrs, b * a);
            else if (str[i] == '/')
                Push(Ptrs, b / a);
            else
                printf("error\n");
        }
        i++;
    }
    int c = Pop(Ptrs);//栈顶的数字出栈
    return c;
}
// 设置符号优先级
int Compare_Priority(char c) {
    if (c == '#') {
        return 0;
    }
    else if (c == '+' || c == '-') {
        return 1;
    }
    else if (c == '*' || c == '/') {
        return 2;
    }
    else if (c == '(' || c == ')') {
        return 0;
    }
    else {
        return -1;
    }
}
int main() {
    char op[MAX];int top = -1;
    char result[MAX];int top1 = -1;
    char str[MAX];
    printf("输入中缀表达式,以#做输入结束的标志:");
    scanf("%s", &str);
    int len = strlen(str);
    printf("转化为后缀表达式后计算结果:");
    for (int i = 0;i < len;) {
        if (Compare_Priority(str[i]) == -1) {
            result[++top1] = str[i++];
        }
        else if (str[i] == '(') {
            op[++top] = str[i++];
        }
        else if (str[i] == ')') {
            while (op[top] != '(') {
                result[++top1] = op[top--];
            }
            top--;
            i++;
        }
        else {
            if (top == -1 || Compare_Priority(str[i]) > Compare_Priority(op[top])) {
                op[++top] = str[i++];
            }
            else {
                while (Compare_Priority(str[i]) <= Compare_Priority(op[top]))
                    result[++top1] = op[top--];
                op[++top] = str[i++];
            }
            if (str[i] == '#') {
                break;
            }
        }
    }
    printf("%d", Calculate(result));
}

测试:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xxx_xiyuyu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值