后缀表达式的计算【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博客

猜你喜欢

转载自blog.csdn.net/weixin_64811333/article/details/127775572
今日推荐