栈的应用2——超级计算器(中缀与后缀表达式)C语言

输入中缀表达式输出结果(结果可以是小数,但输入必须是整数) 

  1 #include<stdio.h>
  2 #include<stdlib.h>    //需要两个栈,一个储存结果,一个储存运算符
  3 #define newpc (stype *)malloc(sizeof(stype))
  4 #define newpi (inttype *)malloc(sizeof(inttype))  //定义两个申请地址的宏
  5 typedef struct char_stack
  6 {
  7  char dat;
  8  struct _stack * next;
  9 } stype;
 10 typedef struct int_stack
 11 {
 12  double dat;
 13  struct _stack * next;     //建立两个栈类型 
 14 } inttype;
 15 void charpush(stype** stacktop,char c)  //运算符压栈函数,需要传进栈顶指针本身的地址,而不是它指向的地址 
 16 {
 17  stype * ss=newpc;
 18  ss->dat=c;
 19  ss->next=*stacktop;
 20  *stacktop=ss;
 21 }
 22 char charpop(stype** stacktop)  //运算符出栈函数 
 23 {
 24  char c=(*stacktop)->dat;
 25  stype *ss=(*stacktop);
 26  (*stacktop)=(*stacktop)->next;
 27  free(ss);
 28  return c;
 29 }
 30 void intpush(inttype** stacktop,double c)  //数字压栈函数 
 31 {
 32  inttype * ss=newpi;
 33  ss->dat=c;
 34  ss->next=*stacktop;
 35  *stacktop=ss;
 36 }
 37 double intpop(inttype** stacktop)  //数字出栈函数 
 38 {
 39  double c=(*stacktop)->dat;
 40  inttype *ss=(*stacktop);
 41  (*stacktop)=(*stacktop)->next;
 42  free(ss);
 43  return c;
 44 }
 45 void tanchu(char c,inttype ** stacktop) //弹出字符,然后运算,然后进栈 
 46 {
 47  double a=intpop(stacktop);
 48  double b=intpop(stacktop);
 49  if (c=='+') intpush(stacktop,b+a);
 50  else if (c=='-') intpush(stacktop,b-a);
 51  else if (c=='*') intpush(stacktop,b*a);
 52  else if (c=='/') intpush(stacktop,b/a);
 53 }
 54 int tance(char c)  //探测优先级的函数 
 55 {
 56  if (c=='+'||c=='-') return 0;
 57  else if (c=='*'||c=='/') return 1;
 58  else if (c=='@'||c=='('||c==')') return -1;
 59 }
 60 int main()  //主函数 功能:处理输入的中缀表达式,输出结果(过程中用到了后缀的转化) 
 61 {
 62  stype * sig,* sigtop;
 63  inttype * num,* numtop;  //每个栈需要两个指针进行操作  
 64  char c=getchar();
 65  sig=newpc;
 66     sig->dat='@';
 67  sig->next=NULL;
 68  sigtop=sig;
 69  num=newpi;
 70  num->next=NULL;
 71  numtop=num;   //初始化两个栈 
 72  while (c!='\n')  //一直读入,直至读到回车符结束 
 73  {
 74   //接下来要对读入的当前字符进行处理
 75   if (c>='0'&&c<='9')
 76   {
 77    int a=c-48;
 78    c=getchar();
 79    while(c>='0'&&c<='9')
 80    {
 81     a=a*10+(c-48);
 82     c=getchar();
 83    }
 84    intpush(&numtop,a);      //如果是个数字字符,就把这个数字一直读进去(因为不一定是几位数),然后压栈到num里 
 85   } 
 86   else if (c=='(')  //如果是左括号,直接压栈到sig里 
 87   {
 88    charpush(&sigtop,'(');
 89    c=getchar();
 90   }
 91   else if (c==')') //如果是右括号,就边弹栈边处理结果,直到遇到左括号 
 92   {
 93    while (sigtop->dat!='(')
 94    {
 95     tanchu(charpop(&sigtop),&numtop);
 96    }
 97    c=getchar();
 98    charpop(&sigtop);
 99   }
100   else if (c=='+'||c=='-'||c=='*'||c=='/') //如果是+-*/就比较与栈顶的优先级,如果高,直接压入,否则(等于也不能压入),边弹边处理结果,直到可以压入(和上面有点像) 
101   {
102    int j=tance(c);
103    int k=tance(sigtop->dat);
104    if (j>k)
105    {
106     charpush(&sigtop,c);
107     c=getchar();
108    }
109    else{
110     while(j<=k)
111     {
112      tanchu(charpop(&sigtop),&numtop);
113      k=tance(sigtop->dat);
114     }
115     charpush(&sigtop,c); 
116     c=getchar();
117    }
118   }
119   else  //否则,忽略这个符号 ,并且显示输入有误 
120   {
121    c='\n';
122    printf("输入有误\n");
123   }
124   
125  }
126  while (sigtop->dat!='@')  //收收尾,把没有弹出的都处理一下 
127  {
128   tanchu(charpop(&sigtop),&numtop);
129  }
130  printf("%.2lf\n",numtop->dat);
131  c=getchar();
132  return 0;
133 }

 

posted @ 2015-08-22 12:18  lvmememe  阅读(1455)  评论(0编辑  收藏  举报