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


    什么是后缀表达式?

    逆波兰表达式_百度百科

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

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

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

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

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

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

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

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

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

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

    具体看下图

     程序源码:

    1. #include
    2. #include
    3. #define Size 100
    4. //堆栈结构体类型
    5. typedef struct stack {
    6. int top;
    7. int nums[Size];
    8. } St;
    9. //函数声明
    10. void ruzhan(St *S, int x);
    11. int chuzhan(St *S);
    12. int main() {
    13. St S;S.top = -1;
    14. int sign = 0, x, x1, x2;
    15. char c;
    16. scanf("%c", &c); //接收一个字符
    17. while (c != '@') { //接收字符直到遇到终止符号
    18. if (c == ' ' && sign == 1) {
    19. sign = 0;
    20. ruzhan(&S, x);
    21. }
    22. if (c >= '0' && c <= '9') {
    23. if (sign != 1) {
    24. x = (int) (c - '0');
    25. sign = 1;
    26. } else {
    27. x = x * 10 + (int) (c - '0');
    28. }
    29. //-----------------------------------
    30. } else {
    31. switch (c) { //判断是否为运算符
    32. case '+':
    33. ruzhan(&S, chuzhan(&S) + chuzhan(&S)); //出栈两次计算其相加结果并入栈
    34. break;
    35. case '-':
    36. x1 = chuzhan(&S); //减数
    37. x2 = chuzhan(&S); //被减数
    38. ruzhan(&S, x2 - x1); //计算差
    39. break;
    40. case '*':
    41. ruzhan(&S, chuzhan(&S) * chuzhan(&S)); //计算乘法
    42. break;
    43. case '/':
    44. x1 = chuzhan(&S); //除数
    45. x2 = chuzhan(&S); //除数
    46. if (x1 == 0) { //除数为0退出
    47. exit(0);
    48. } //合法则将其商入栈
    49. ruzhan(&S, x2 / x1); //计算商
    50. break;
    51. }
    52. }
    53. scanf("%c", &c); //继续接收字符
    54. }
    55. printf("后缀表达式计算结果:%d", chuzhan(&S)); //输出结算结果
    56. }
    57. int chuzhan(St *S) {
    58. St *p = S;
    59. if (p->top < 0) {
    60. exit(0);
    61. } else {
    62. return p->nums[(p->top)--];
    63. }
    64. }
    65. void ruzhan(St *S, int n) {
    66. St *p = S;
    67. if (p->top >= Size - 1) {
    68. return;
    69. } else {
    70. (p->top)++;
    71. p->nums[p->top] = n;
    72. }
    73. }

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

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

     

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

     

    1. if (c == ' ' && sign == 1) {
    2. sign = 0;
    3. ruzhan(&S, x);
    4. }
    5. if ( c <= '9'&&c >= '0' ) {
    6. if (sign != 1) {
    7. x = (int) (c - '0');
    8. sign = 1;
    9. } else {
    10. x = x * 10 + (int) (c - '0'); //累加和
    11. }
    12. }

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

  • 相关阅读:
    对比Excel学openpyxl系列之设置excel数字和条件格式
    redis的基础底层篇 zset的详解
    Momenta“飞轮式L4”接受夜间长尾场景「像素级」挑战,表现堪比老司机
    B/B+树索引和哈希索引
    单视觉L2市场「鲶鱼」来了,掀起数据反哺高阶新打法
    CVE-2023-46227 Apache inlong JDBC URL反序列化漏洞
    Java高岗BAT面试必问115题包括Spring、微服务、SpringMVC、MyBatis
    python之opencv人脸识别快速体验
    C/C++语言100题练习计划 97——素数对
    【AI+医疗】AI在医疗影像设备工作周期中的应用探索
  • 原文地址:https://blog.csdn.net/weixin_64811333/article/details/127775572