栈与队列(四)中缀计算器代码
来源:互联网 发布:php属于前端还是后端 编辑:程序博客网 时间:2024/05/22 08:16
中缀计算器(先中缀转后缀,再RPN计算)
关于代码想说的:
1.有人会问为什么要做两个栈 解决:因为在中缀转后缀中第一个栈被销毁的
2.缓冲量的作用 解决:接收空格
3.如何结合中缀转后缀和RPN计算 解决:将中缀转后追的输出放进数组string中,然后在RPN计算中本来要输入的直接在数组里拿就好,注意不要忘记空格
/************************************************************************* > File Name: 中缀计算器.c > Author: geeker > Mail: 932834897@qq.com > Created Time: 2017年02月08日 星期三 15时32分41秒 ************************************************************************/#include <stdio.h>#include <stdlib.h>#include <malloc.h>#include <math.h>#include <ctype.h>#define stacksize 20//栈的最大容量#define maxbuffer 10//缓冲量char string[50];//定义一个字符数组,将中缀转后缀的输出数据放到数组中,再取数组元素进行逆波兰计算typedef char ElemType;//19-25行是给中缀转后缀用的typedef struct{ ElemType *base; ElemType *top; int maxsize;}sqStack;typedef double bElemType;//28-33行是给逆波兰计算用的typedef struct{ bElemType *base; bElemType *top; int maxsize;}bsqStack;void InitStack(sqStack *s)//初始化{ s->base=(ElemType *)malloc(stacksize * sizeof(ElemType)); if(!s->base)//分配失败退出程序 { exit(0); } s->top=s->base; s->maxsize=stacksize;}void Push(sqStack *s,ElemType e)//压栈{ if(s->top-s->base>=s->maxsize) { return; } *(s->top)=e;//给当前栈顶赋值 s->top++;//栈顶元素加1}void Pop(sqStack *s,ElemType *e)//出栈{ if(s->top==s->base) { return; } *e=*--(s->top);}int StackLen(sqStack s)//计算容量{ return(s.top-s.base);}void bInitStack(bsqStack *s)//再次初始化(为什么要再次初始化、压栈等等,因为在中转后的change函数中已经把栈给销毁了,所以要重新建立){ s->base=(bElemType *)malloc(stacksize * sizeof(bElemType)); if(!s->base) { exit(0); } s->top=s->base; s->maxsize=stacksize;}void bPush(bsqStack *s,bElemType e)//再次压栈{ if(s->top-s->base>=s->maxsize) { return; } *(s->top)=e; s->top++;}void bPop(bsqStack *s,bElemType *e)//再次出栈{ if(s->top==s->base) { return; } *e=*--(s->top);}int bStackLen(bsqStack s)//再次求栈容量{ return(s.top-s.base);}void DestroyStack(sqStack *s)//销毁栈{ free(s->base); s->base=s->top=NULL; s->maxsize=0;}void DestroyBStack(bsqStack *s)//再次销毁栈{ free(s->base); s->base=s->top=NULL; s->maxsize=0;}int change()//就是中缀转后缀的一个函数,然而区别就在于将输出的数据存入到string数组中,所以每一次printf就会跟string[i++];{ sqStack s; char c,e; InitStack(&s); int i=0; printf("请输入中缀表达式,以#为结束标志\n"); scanf("%c",&c); while(c!='#') { while(c>='0'&&c<='9') { printf("%c",c); string[i++]=c;//关键。。把输出的数据放到数组中 scanf("%c",&c); if(c<'0'||c>'9') { printf(" "); string[i++]=' '; } } if(')'==c) { Pop(&s,&e); while('('!=e){ printf("%c ",e); string[i++]=e; string[i++]=' '; Pop(&s,&e); } } else if('+'==c||'-'==c) { if(!StackLen(s)) { Push(&s,c); } else { do { Pop(&s,&e); if('('==e) { Push(&s,e); } else { printf("%c",e); string[i++]=e; } }while(StackLen(s)&&'('!=e); Push(&s,c); } } else if('*'==c||'/'==c||'('==c) { Push(&s,c); } else if('#'==c) { break; } else { printf("\n出错,程序输入错误\n"); return -1; } scanf("%c",&c); } while(StackLen(s)) { Pop(&s,&e); printf("%c ",e); string[i++]=e; string[i++]=' '; } printf("\n"); string[i]='\0'; printf("%s\n",string); string[i]='#';//这里特别重要,很容易忘记,忘记了很难找到错误,切记! DestroyStack(&s); return 0;}int main()//这个main函数其实就是一个逆波兰计算器,区别就是将数组中的数据当做本来要输入的字符,即char *p=string;c=*p++;然后c就是那个看做输入的字符,逆波兰在前面的博客已经有算法,不多解释{ bsqStack s; char c; double d,e; char str[maxbuffer];//缓冲 int f=0; change(); bInitStack(&s); printf("请按逆波兰表达式输入带计算数据,数据与运算符之间用空格隔开,以#作为结束标志\n"); char *p=string;//关键 c=*p++; while(c!='#') { while(isdigit(c)||c=='.') { str[f++]=c; str[f]='\0'; if(f>=10) { printf("error,输入单个数据过大\n"); return -1; }//缓冲区最大范围 // scanf("%c",&c) c=*p++;//这里本来是输入的,但所有数据已存在数组中 if(c==' ') { d=atof(str);//功能 bPush(&s,d); f=0; break; } } switch(c) { case'+': bPop(&s,&e); bPop(&s,&d); bPush(&s,d+e); break; case'-': bPop(&s,&e); bPop(&s,&d); bPush(&s,d-e); break; case'*': bPop(&s,&e); bPop(&s,&d); bPush(&s,d*e); break; case'/': bPop(&s,&e); bPop(&s,&d); if(e!=0) { bPush(&s,d/e); } else { printf("\nerror,除数不能为0\n"); return -1; } break; } // scanf("%c",&c); c=*p++; } bPop(&s,&d); printf("\n最终计算结果为: %lf\n",d); DestroyBStack(&s);//别忘记销毁栈 return 0;}
5 0
- 栈与队列(四)中缀计算器代码
- 栈与队列(三)中缀表达式转后缀表达式
- 利用栈做的中缀计算器雏形
- 【栈/中缀转后缀】HDU1237简单计算器
- 计算器C++代码实现—— 中缀表达式的计算
- 数据结构(四)栈与队列
- 中缀表达式计算器
- 【JS】中缀表达式计算器
- 中缀表达式计算器
- 中缀表达式计算器
- 栈与队列(二)之逆波兰(RPN)计算器
- 【数据结构】第2周 栈与队列 4:中缀表达式的值
- 逆波兰计算器与中缀表达式向后缀表达式的转化实例
- 数据结构与算法之栈与队列<四>
- [栈和队列]从中缀向后缀转换表达式
- 用栈和队列实现中缀表达式的求解
- 四.队列与双端队列
- 接上篇文章的中缀与后缀的代码实现
- 417. Pacific Atlantic Water Flow dfs
- Scala学习笔记 --- scala中 => 作用
- 共生矩阵纹理特征提取
- springmvc使用流程
- 混杂设备驱动模型设计LED驱动
- 栈与队列(四)中缀计算器代码
- Ubuntu 下真机调试 Android
- 菜鸟笔记的第一天,自定义View(组合控件)
- JavaWeb(框架--Hibernate):----配置
- Unity—项目开发中常用模块(吐血整理笔记摘要)--------持续更新中... ...
- java Native Method
- 小P寻宝记——粗心的基友
- eclipse中使用Ctrl+Alt+↑或↓时屏幕旋转的问题
- 浮动布局所带来的影响以及如何清除浮动