鱼C论坛

 找回密码
 立即注册
查看: 2642|回复: 0

[学习笔记] C语言实现整数的逆波兰计算器,包括后缀转换和结果计算

[复制链接]
发表于 2020-7-26 22:30:10 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 慕容紫小英 于 2020-7-26 23:09 编辑

这几天在学习数据结构,网上的代码有大多对基础差的人不太友好,写的比较难懂,我自己也是基础较差,但是我要求自己用自己的方式实现这些经典的程序设计,同时也希望给和我一样跨考计算机的朋友提供一些可供参考的源代码。

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <ctype.h>
  4. #include <string.h>

  5. #define maxsize 100

  6. /*本人也是跨考党,已经将代码尽我所能的解释清楚明白,方便于像我一样的初学者观看学习*/

  7. typedef struct SqStack//定义栈
  8. {
  9.         char data[maxsize];
  10.         int top;
  11. }SqStack;

  12. int push(SqStack *st,char x)//入栈
  13. {
  14.         if((*st).top == maxsize-1)
  15.                 return 0;
  16.         ++((*st).top);
  17.         (*st).data[(*st).top] = x;
  18.         return 1;
  19. }

  20. int pop(SqStack *st,char *x)//出栈
  21. {
  22.         if((*st).top == -1)
  23.                 return 0;
  24.         *x = (*st).data[(*st).top];
  25.         --((*st).top);
  26.         return 1;
  27. }
  28. //中缀表达式转换为逆波兰式
  29. //思路:1.定义两个栈,一个存放数字,称为num栈,一个存放运算符( + - * / ),称为opera栈
  30. //      2.从左至右逐个遍历字符数组,分为以下两种情况
  31. //         如果是数字直接入栈num
  32. //         如果是运算符:
  33. //         (1)opera为空,直接压入
  34. //         (2)运算符为左括号'(',直接压入opera
  35. //         (3) 运算符为'+' '-' '*' '/' ,则判断当前opera的栈顶元素,并比较优先级
  36. //               一般来说,乘法 = 除法 > 加法 = 减法
  37. //               如果栈顶元素优先级高,则将栈顶元素移出并压入栈num中 ,再将当前运算符压入栈opera中
  38. //               需要注意的是,平级的运算符也是要出栈的
  39. //          (4)运算符为右括号')',连续将opera的栈顶元素压入num中直至碰见左括号'(' ,并将左括号'('移出栈
  40. //      3.读到'\0'之后,将栈opera剩余元素全部压入栈num
  41. void RPN_switch(SqStack *A,SqStack *B,char ss[])
  42. {  
  43.         int i;
  44.         char temp;//记录出栈元素
  45.        
  46.         for(i = 0;i < maxsize;i++)
  47.         {
  48.                 if(ss[i] == '\0')
  49.                         break;
  50.                 else
  51.                 if(isdigit(ss[i]))//数字直接入栈num
  52.                 {
  53.                         push(A,ss[i]);
  54.                 }
  55.                 else
  56.                 {
  57.                         if(isdigit(ss[i-1]))
  58.                         {
  59.                                 push(A,' ');//此处的操作是为了分割多位数和个位数,碰见运算符之前如果是数字则将一个' '(空格)压入栈num中
  60.                         }       
  61.                         switch(ss[i])//碰见运算符,进行上述判断再压入栈opera
  62.                         {
  63.                                 case '(':{
  64.                                                 push(B,ss[i]);
  65.                                                 break;
  66.                                              }
  67.                                 case '+':{
  68.                                                  if((*B).top == -1)
  69.                                                  {
  70.                                                          push(B,ss[i]);
  71.                                                          break;
  72.                                                  }
  73.                                                  else
  74.                                                  {
  75.                                                          switch((*B).data[(*B).top])
  76.                                                          {
  77.                                                                  case '+':{
  78.                                                                                         pop(B,&temp);
  79.                                                                                           push(A,temp);
  80.                                                                                           push(B,ss[i]);
  81.                                                                                           break;
  82.                                                                               }
  83.                                                                
  84.                                                                  case '-':{
  85.                                                                                           pop(B,&temp);
  86.                                                                                           push(A,temp);
  87.                                                                                           push(B,ss[i]);
  88.                                                                                           break;
  89.                                                                               }
  90.                                                                  case '*':{
  91.                                                                                           pop(B,&temp);
  92.                                                                                           push(A,temp);
  93.                                                                                           push(B,ss[i]);
  94.                                                                                           break;
  95.                                                                               }
  96.                                                                  case '/':{
  97.                                                                                           pop(B,&temp);
  98.                                                                                           push(A,temp);
  99.                                                                                           push(B,ss[i]);
  100.                                                                                           break;
  101.                                                                               }
  102.                                                                  case '(':{
  103.                                                                                           push(B,ss[i]);
  104.                                                                                           break;
  105.                                                                               }
  106.                                                          }
  107.                                                          break;
  108.                                                  }
  109.                                          }         
  110.                                 case '-':{
  111.                                                  if((*B).top == -1)
  112.                                                  {
  113.                                                          push(B,ss[i]);
  114.                                                          break;
  115.                                                  }
  116.                                                  else
  117.                                                  {
  118.                                                          switch((*B).data[(*B).top])
  119.                                                          {
  120.                                                                  case '+':{
  121.                                                                                           pop(B,&temp);
  122.                                                                                           push(A,temp);
  123.                                                                                           push(B,ss[i]);
  124.                                                                                           break;
  125.                                                                                     }
  126.                                                                
  127.                                                                  case '-':{
  128.                                                                                           pop(B,&temp);
  129.                                                                                           push(A,temp);
  130.                                                                                           push(B,ss[i]);
  131.                                                                                           break;
  132.                                                                                     }
  133.                                                                  case '*':{
  134.                                                                                           pop(B,&temp);
  135.                                                                                           push(A,temp);
  136.                                                                                           push(B,ss[i]);
  137.                                                                                           break;
  138.                                                                               }
  139.                                                                  case '/':{
  140.                                                                                           pop(B,&temp);
  141.                                                                                           push(A,temp);
  142.                                                                                           push(B,ss[i]);
  143.                                                                                           break;
  144.                                                                               }
  145.                                                                  case '(':{
  146.                                                                                           push(B,ss[i]);
  147.                                                                                           break;
  148.                                                                               }
  149.                                                          }
  150.                                                          break;
  151.                                                  }
  152.                                          }
  153.                                 case '*':{
  154.                                                  if((*B).data[(*B).top]=='/')
  155.                                                  {
  156.                                                         pop(B,&temp);
  157.                                                         push(A,temp);
  158.                                                         push(B,ss[i]);
  159.                                                         break;
  160.                                                  }
  161.                                                  else
  162.                                                  {         
  163.                                                          push(B,ss[i]);
  164.                                                          break;
  165.                                                  }
  166.                                          }
  167.                                 case '/':{
  168.                                                  if((*B).data[(*B).top]=='*')
  169.                                                  {
  170.                                                         pop(B,&temp);
  171.                                                         push(A,temp);
  172.                                                         push(B,ss[i]);
  173.                                                         break;
  174.                                                  }
  175.                                                  else
  176.                                                  {         
  177.                                                          push(B,ss[i]);
  178.                                                          break;
  179.                                                  }
  180.                                          }
  181.                                 case ')':{
  182.                                                  do
  183.                                                  {
  184.                                                          pop(B,&temp);
  185.                                                          push(A,temp);
  186.                                                  }while((*B).data[(*B).top]!='(');
  187.                                                  pop(B,&temp);
  188.                                                  break;
  189.                                          }         
  190.                         }
  191.                 }

  192.         }

  193.         do
  194.         {
  195.                 pop(B,&temp);
  196.                 push(A,temp);
  197.         }while((*B).top > -1);
  198.         push(A,'\0');//栈opera元素全部压入栈num之后,栈num最后别忘了补'\0'
  199.         strcpy(ss,(*A).data);//用栈num替换原来的字符数组
  200.         printf("%s",ss);
  201. }

  202. double Operation(double a,char op,double b)//计算器中的两元操作,由于除法的存在,数据类型选择double
  203. {
  204.         if(op == '+')
  205.                 return a+b;
  206.         if(op == '-')
  207.                 return a-b;
  208.         if(op == '*')
  209.                 return a*b;
  210.         if(op == '/')
  211.         {
  212.                 if(b == 0)
  213.                 {
  214.                         printf("分母不能为0!\n");
  215.                         return 0;
  216.                 }
  217.                 else
  218.                 {
  219.                         return a/b;
  220.                 }
  221.         }
  222. }

  223. void Calculator(char ss[])//计算器的代码部分
  224. {
  225.         int i;
  226.         double a,b,c;//a,b取出字符数组中的数字,c是两数进行计算之后的结果
  227.         double result[maxsize];//定义一个double类型的栈
  228.         int top = -1;
  229.         char op;//记录运算符

  230.         for(i = 0;i < maxsize;i++)
  231.         {
  232.                 if(ss[i] == '\0')
  233.                         break;
  234.                 else
  235.                 if(isdigit(ss[i]))//此处是将char类型的数字转化为int类型
  236.                 {
  237.                         if(isdigit(ss[i-1]))//碰到数字,判断前一个是否为数字,如果是那么就是多位数
  238.                         {
  239.                                 result[top] = result[top]*10+(ss[i]-'0');//直接将栈中的数字乘以10加上新读到的数字
  240.                         }
  241.                         else//如果前面不是数字就压入新的数字
  242.                         {
  243.                                 result[++top] = ss[i]-'0';
  244.                         }
  245.                 }
  246.                 else
  247.                 if(ss[i]=='+'||ss[i]=='-'||ss[i]=='*'||ss[i]=='/')//碰见运算符则应该处理栈顶的两数字了
  248.                 {
  249.                         op = ss[i];
  250.                         b = result[top--];
  251.                         a = result[top--];
  252.                         c = Operation(a,op,b);
  253.                         result[++top] = c;
  254.                 }
  255.         }

  256.         printf(" = %f\n",result[top]);
  257. }

  258. int main(void)
  259. {
  260.         printf("欢迎使用逆波兰计算器!\n");
  261.         printf("请输入您希望计算的表达式!\n");
  262.        
  263.         char ss[maxsize];
  264.         int i = 0;
  265.         fgets(ss,maxsize,stdin);

  266.         SqStack num;
  267.         SqStack opera;
  268.         num.top = -1,opera.top = -1;

  269.         RPN_switch(&num,&opera,ss);
  270.         Calculator(ss);

  271.         return 0;
  272. }
复制代码

评分

参与人数 1荣誉 +5 鱼币 +1 收起 理由
jpan1221 + 5 + 1

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-8 11:17

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表