后缀表达式的计算【C语言】【数据结构】

什么是后缀表达式?

逆波兰表达式_百度百科

后缀表达式又称(逆波兰表达式)先看一下我们常见的:2 * 5 - ( 3  + 9 ) / 6,这其实就是中缀表达式;将其写成后缀表达式就是:

2   5  *  3   9  +  6  /  -  (每个字符用空格隔开)。

中缀表达式到后缀表达式怎么变的??为什么要这么写??

中缀表达式到后缀表达式其实很简单:

1.首先为每一个运算符的一对操作数加上括号。(+、-、*、/  都属于二目运算符)

2.将每个括号中的运算符提到括号的做右边(这就是为啥叫后缀表达式的原因,你提到括号前面它就是前缀表达式了)。

3.去掉所有括号。为了方便观察,每一个数字/运算符 都用空格间隔开

首先回答一下为什么要这么写。这其实是为了方便计算机来计算,就先刚才上面的式子,如果是人来算,你很清楚的直到要先计算括号里的,然后计算乘除再计算加减。但计算机就没这么“聪明”了。如果交给计算机来算,你得把他写成后缀表达式的形式。

这懂了,那么如何计算呢?

后缀表达式就是为了方便“无脑计算”。中缀表达式计算需要分优先级,在后缀表达式的计算过程中就不用管这么多,遇到运算符直接计算即可(需要注意的是,如果是减‘-’或者除‘/’,需要将先出栈的结果作为除数,后出栈的作为被除数,这一点在后面代码部分体现),总之就一条规则===》》“后出栈元素 (+、-、*、/)先出栈元素”。(这里仍然考虑的比较简单,忽略了除数可能为0 的情况)。

具体看下图

 程序源码:

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

#define Size 100
//堆栈结构体类型
typedef struct stack {
    int top;
    int nums[Size];
} St;

//函数声明
void ruzhan(St *S, int x);

int chuzhan(St *S);

int main() {
    St S;S.top = -1;
    int sign = 0, x, x1, x2;
    char c;
    scanf("%c", &c);   //接收一个字符
    while (c != '@') { //接收字符直到遇到终止符号
        if (c == ' ' && sign == 1) {
            sign = 0;
            ruzhan(&S, x);
        }
        if (c >= '0' && c <= '9') {
            if (sign != 1) {
                x = (int) (c - '0');
                sign = 1;
            } else {
                x = x * 10 + (int) (c - '0');
            }
            //-----------------------------------
        } else {
            switch (c) {   //判断是否为运算符
                case '+':
                    ruzhan(&S, chuzhan(&S) + chuzhan(&S)); //出栈两次计算其相加结果并入栈
                    break;
                case '-':
                    x1 = chuzhan(&S);    //减数
                    x2 = chuzhan(&S);    //被减数
                    ruzhan(&S, x2 - x1); //计算差
                    break;
                case '*':
                    ruzhan(&S, chuzhan(&S) * chuzhan(&S)); //计算乘法
                    break;
                case '/':
                    x1 = chuzhan(&S);    //除数
                    x2 = chuzhan(&S);    //除数
                    if (x1 == 0) {       //除数为0退出
                        exit(0);
                    }   //合法则将其商入栈
                    ruzhan(&S, x2 / x1); //计算商
                    break;
            }
        }
        scanf("%c", &c);   //继续接收字符
    }
    printf("后缀表达式计算结果:%d", chuzhan(&S));   //输出结算结果
}

int chuzhan(St *S) {
    St *p = S;
    if (p->top < 0) {
        exit(0);
    } else {
        return p->nums[(p->top)--];
    }
}

void ruzhan(St *S, int n) {
    St *p = S;
    if (p->top >= Size - 1) {
        return;
    } else {
        (p->top)++;
        p->nums[p->top] = n;
    }
}

忘了说,2 * 5 - ( 3  + 9 ) / 6的计算结果为8;

使用刚写的程序计算其后缀表达式:2   5  *  3   9  +  6  /  - 。结果必须得一致;运行结果见下图:

 

关于其中如下的一段代码,其作用是将输入的连续数字字符转换为对应位数的数,例如字符串“123”,将其转化为数字一百二十三。如果没有一下算法支持,该程序只能计算运算数为-9到+9的范围。

 

if (c == ' ' && sign == 1) {
   sign = 0;
   ruzhan(&S, x);
}
if ( c <= '9'&&c >= '0' ) {
    if (sign != 1) {
        x = (int) (c - '0');
        sign = 1;
    } else {
        x = x * 10 + (int) (c - '0');   //累加和
    }
} 

其实和单词判断思路大差不差:【C语言】输入一行字符串,统计其中的单词数_.魚肉的博客-CSDN博客

  • 7
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是将后缀表达式转化成表达树的 C 语言代码,其中使用了栈(Stack)数据结构。 ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> struct node { char data; struct node *left; struct node *right; }; // 栈结构体 struct stack { int top; struct node **items; }; // 创建新节点 struct node *createNode(char data) { struct node *newNode = (struct node *)malloc(sizeof(struct node)); newNode->data = data; newNode->left = NULL; newNode->right = NULL; return newNode; } // 初始化栈 struct stack *createStack(int capacity) { struct stack *newStack = (struct stack *)malloc(sizeof(struct stack)); newStack->top = -1; newStack->items = (struct node **)malloc(capacity * sizeof(struct node *)); return newStack; } // 判断栈是否为空 int isEmpty(struct stack *s) { return s->top == -1; } // 判断栈是否已满 int isFull(struct stack *s) { return s->top == 99; } // 入栈 void push(struct stack *s, struct node *item) { if (isFull(s)) { printf("Stack is full\n"); return; } s->items[++s->top] = item; } // 出栈 struct node *pop(struct stack *s) { if (isEmpty(s)) { printf("Stack is empty\n"); return NULL; } return s->items[s->top--]; } // 从后缀表达式中构造表达树 struct node *constructTree(char postfix[]) { struct stack *s = createStack(strlen(postfix)); struct node *t, *t1, *t2; for (int i = 0; postfix[i] != '\0'; i++) { if (isdigit(postfix[i])) { t = createNode(postfix[i]); push(s, t); } else { t = createNode(postfix[i]); t1 = pop(s); t2 = pop(s); t->right = t1; t->left = t2; push(s, t); } } t = pop(s); free(s); return t; } // 中序遍历表达树 void inorder(struct node *t) { if (t) { inorder(t->left); printf("%c ", t->data); inorder(t->right); } } int main() { char postfix[] = "ab+cd-*"; struct node *root = constructTree(postfix); printf("Infix expression: "); inorder(root); return 0; } ``` 程序中定义了 `struct node` 结构体表示表达树的节点,`struct stack` 结构体表示栈的数据结构。`createNode` 函数用于创建新节点,`createStack` 函数用于初始化栈。 `isEmpty` 和 `isFull` 函数分别用于判断栈是否为空和已满。`push` 函数用于入栈,`pop` 函数用于出栈。 `constructTree` 函数用于将后缀表达式转化成表达树,程序中使用栈来辅助构造表达树。该函数遍历后缀表达式,如果当前字符是数字,则创建一个新节点并将其入栈。如果当前字符是操作符,则弹出栈顶的两个节点,将当前字符作为新节点的值,将弹出的两个节点分别作为新节点的左右子节点,最后将新节点入栈。 `inorder` 函数用于中序遍历表达树,输出中序遍历的结果即为中缀表达。 在 `main` 函数中,定义了一个后缀表达式字符串 `postfix`,通过 `constructTree` 函数将其转换成表达树,并通过 `inorder` 函数输出中缀表达

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

.魚肉

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

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

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

打赏作者

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

抵扣说明:

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

余额充值