逆波兰计算器的实现
来源:互联网 发布:mac键盘灯怎么开 编辑:程序博客网 时间:2024/04/28 18:23
话不多说先上代码供大佬们检查
#include"stdio.h"#include"stdlib.h"#include"memory.h"#define MAXSIZE 100typedef struct MStack{char data[MAXSIZE];int top;};MStack *InitStack(){MStack *ms;ms = (MStack*)malloc(sizeof(MStack));memset(ms->data, 0, MAXSIZE);ms->top = -1;return ms;}void PushStack(MStack *ms, char e){if (ms->top == MAXSIZE - 1){printf("栈满溢出");return;}ms->data[++ms->top] = e;}void PopStack(MStack *ms, char *e){if (ms->top == -1){printf("栈空!");return;}*e = ms->data[ms->top--];}int PriCal(char c){if (c == '-' || c == '+')return 1;if (c == '*' || c == '/')return 2;if (c == '(' || c == ')')return 3;return false;}int main(){MStack *ms;MStack *msn;msn = InitStack();ms = InitStack();char above = 9;//保存上一次的输入值,检测输入算式是否合法char c;char num;int e;c = getchar();//以下是将普通中缀表达式改为后缀表达式while (1){e = 0;//if (c == '\n')//{//if (!(above != ')' || (above <= '9' && above >= '0')))//{//printf("输入算式有错,请检查后重新运行此程序!");//return -1;//}//while (ms->top != -1)//{//PopStack(ms, &c);//PushStack(msn, c);//}//break;//}if (c <= '9' && c >= '0'){if (ms->top != -1){if (above != '+' && above != '-' && above != '*' && above != '/' && above != '('){printf("输入算式有错,请检查后重新运行此程序!");return -1;}}while (c <= '9' && c >= '0'){e = e * 10 + c - '0';above = c;c = getchar();}PushStack(msn, (char)(e + '0'));}if (c == '+' || c == '-' || c == '*' || c == '/'){if (!(above != ')' || (above <= '9' && above >= '0'))){printf("输入算式有错,请检查后重新运行此程序!");return -1;}if (ms->top == -1)PushStack(ms, c);else if (PriCal(ms->data[ms->top]) >= PriCal(c)){while (PriCal(ms->data[ms->top]) >= PriCal(c)){if (ms->data[ms->top] == '(')break;num = c;PopStack(ms, &num);PushStack(msn, num);}PushStack(ms, c);}else PushStack(ms, c);}if (c == '(' || c == ')'){if (c == '('){if (above != '+' &&above != '-' &&above != '*' &&above != '/'&&ms->top != -1){printf("输入算式有错,请检查后重新运行此程序!");return -1;}PushStack(ms, c);}if (c == ')'){if (above < '0' || above > '9'){printf("输入算式有错,请检查后重新运行此程序!");return -1;}while (c != '('){PopStack(ms, &c);if (c != '(')PushStack(msn, c);}}}above = c;if (c == '\n')break;else c = getchar();}while (msn->top != -1){PopStack(msn, &c);PushStack(ms, c);}/*PushStack(ms, '+');PushStack(ms, '/');PushStack(ms, '2');PushStack(ms, '8');PushStack(ms, '+');PushStack(ms, '*');PushStack(ms, '3');PushStack(ms, '-');PushStack(ms, '1');PushStack(ms, '3');PushStack(ms, '9');*///以下是计算部分while (ms->top != -1){if (ms->data[ms->top] <= '0' + 255 && ms->data[ms->top] >= '0')//原本数据范围是'0'-'9',如果要计算10以外则需要加大为'0'-'0'+255{PopStack(ms, &c);PushStack(msn, c);}if (ms->data[ms->top] == '+'){PopStack(ms, &c);PopStack(msn, &c);PopStack(msn, &num);num = (int)(num - '0') + (int)(c - '0') + '0';PushStack(msn, num);}if (ms->data[ms->top] == '-'){PopStack(ms, &c);PopStack(msn, &c);PopStack(msn, &num);num = (int)(num - '0') - (int)(c - '0') + '0';PushStack(msn, num);}if (ms->data[ms->top] == '/'){PopStack(ms, &c);PopStack(msn, &c);PopStack(msn, &num);num = (char)(int)(num - '0') / (int)(c - '0') + '0';PushStack(msn, num);}if (ms->data[ms->top] == '*'){PopStack(ms, &c);PopStack(msn, &c);PopStack(msn, &num);num = (int)(c - '0')*(int)(num - '0') + '0';PushStack(msn, num);}}printf("%d", msn->data[msn->top] - '0');return 0;}
以上就是我的全部代码
逆波兰算法无非是中缀表达式转换为后缀表达式,然后通过后缀表达式求值。刚开始尝试的时候想法比较大一直想一次性实现,耽误我一天时间,后面分两个模块就实现挺快的 == 。
栈的基本操作没啥可以说的,那我们就不说了,先说说实现后缀表达式的计算这块,
while (ms->top != -1){if (ms->data[ms->top] <= '9' && ms->data[ms->top] >= '0')//原本数据范围是'0'-'9',如果要计算10以外则需要加大为'0'-'0'+255{PopStack(ms, &c);PushStack(msn, c);}if (ms->data[ms->top] == '+'){PopStack(ms, &c);PopStack(msn, &c);PopStack(msn, &num);num = (int)(num - '0') + (int)(c - '0') + '0';PushStack(msn, num);}if (ms->data[ms->top] == '-'){PopStack(ms, &c);PopStack(msn, &c);PopStack(msn, &num);num = (int)(num - '0') - (int)(c - '0') + '0';PushStack(msn, num);}if (ms->data[ms->top] == '/'){PopStack(ms, &c);PopStack(msn, &c);PopStack(msn, &num);num = (char)(int)(num - '0') / (int)(c - '0') + '0';PushStack(msn, num);}if (ms->data[ms->top] == '*'){PopStack(ms, &c);PopStack(msn, &c);PopStack(msn, &num);num = (int)(c - '0')*(int)(num - '0') + '0';PushStack(msn, num);}}
此时数据只接受'0'-'9'的数字的加减法,一次次输入太麻烦我就一次性给输入为9 3 1 - 3 * + 8 2 / +;9是栈顶元素,这相当于计算9+(3-1)*3+8/2,结果算出来没有啥错误,这块是比较简单的。
MStack *ms;MStack *msn;msn = InitStack();ms = InitStack();char above = 9;//保存上一次的输入值,检测输入算式是否合法char c;char num;int e;c = getchar();//以下是将普通中缀表达式改为后缀表达式 while (1) { if (c == '\n') { while (ms->top != -1) { PopStack(ms, &c); PushStack(msn, c); } break; } if (c <= '9' && c >= '0') PushStack(msn, c); if (c == '+' || c == '-' || c == '*' || c == '/') { if (ms->top == -1) PushStack(ms, c); else if (PriCal(ms->data[ms->top]) >= PriCal(c)) { while (PriCal(ms->data[ms->top]) >= PriCal(c)) { if (ms->data[ms->top] == '(')break; num = c; PopStack(ms, &num); PushStack(msn, num); } PushStack(ms, c); } else PushStack(ms, c); } if (c == '(' || c == ')') { if (c == '(')PushStack(ms, c); if (c == ')') { while (c != '(') { PopStack(ms, &c); if(c != '(') PushStack(msn, c); } } } c = getchar(); }
我们现在实现了中后缀表达式转化,这儿关注的只是加减乘除的表达式转化,没怎么注意数字的,但是这样数字也差不多(如果只是单个字符的话)
我们给程序加个错误判断,above存储上一个输入的字符的值,如果我们这次输入为数字上次就必须是左括号或者操作符其它判断类似。但是如果栈内数据为空还需要单独判断。
同时再加个小小的操作让数据能处理非单个字符的运算
MStack *ms; MStack *msn; msn = InitStack(); ms = InitStack(); char above = 9;//保存上一次的输入值,检测输入算式是否合法 char c; char num; int e; c = getchar(); //以下是将普通中缀表达式改为后缀表达式 while (1) { e = 0; //if (c == '\n') //{ //if (!(above != ')' || (above <= '9' && above >= '0'))) //{ // printf("输入算式有错,请检查后重新运行此程序!"); // return -1; //} //while (ms->top != -1) //{ // PopStack(ms, &c); // PushStack(msn, c); //} //break; //} if (c <= '9' && c >= '0') { if (ms->top != -1) { if (above != '+' && above != '-' && above != '*' && above != '/' && above != '(') { printf("输入算式有错,请检查后重新运行此程序!"); return -1; } } while (c <= '9' && c >= '0') { e = e * 10 + c - '0'; above = c; c = getchar(); } PushStack(msn, (char)(e + '0')); } if (c == '+' || c == '-' || c == '*' || c == '/') { if (!(above != ')' || (above <= '9' && above >= '0'))) { printf("输入算式有错,请检查后重新运行此程序!"); return -1; } if (ms->top == -1) PushStack(ms, c); else if (PriCal(ms->data[ms->top]) >= PriCal(c)) { while (PriCal(ms->data[ms->top]) >= PriCal(c)) { if (ms->data[ms->top] == '(')break; num = c; PopStack(ms, &num); PushStack(msn, num); } PushStack(ms, c); } else PushStack(ms, c); } if (c == '(' || c == ')') { if (c == '(') { if (above != '+' &&above != '-' &&above != '*' &&above != '/'&&ms->top != -1) { printf("输入算式有错,请检查后重新运行此程序!"); return -1; } PushStack(ms, c); } if (c == ')') { if (above < '0' || above > '9') { printf("输入算式有错,请检查后重新运行此程序!"); return -1; } while (c != '(') { PopStack(ms, &c); if (c != '(') PushStack(msn, c); } } } above = c; if (c == '\n')break; else c = getchar(); }
注意在最后的c=getchar()前一定要加个c是否为换行符的判断,因为其它读取字符的操作可能它后面需要读取字符的时候,我们的输入已经没有字符了,又得让我们继续输入导致算式出错,同时记得把后缀表达式计算的数据范围改成
if (ms->data[ms->top] <= '0' + 255 && ms->data[ms->top] >= '0')//原本数据范围是'0'-'9',如果要计算10以外则需要加大为'0'-'0'+255
阅读全文
1 0
- 逆波兰计算器的实现
- 逆波兰实现计算器
- 实现逆波兰表达式的java计算器
- java 实现逆波兰计算器
- C语言实现的简单的逆波兰计算器
- 基于逆波兰RPN算法的计算器实现
- 逆波兰 计算器 C语言实现代码
- C语言栈实现逆波兰计算器
- c用栈实现逆波兰计算器
- 逆波兰 计算器 C语言实现
- Java计算器实现(逆波兰式)
- 简单的逆波兰基本计算器
- 逆波兰表达式思想下的计算器
- 基于逆波兰表达式的计算器
- 数据结构(6)--逆波兰计算器的运用
- 用逆波兰表达式的三角函数计算器
- 逆波兰计算器
- 计算器 | 逆波兰表达式
- ECMAScript6-let与const命令详解
- HDU6106-Classes
- Linux C 函数指针应用---回调函数
- 面向对象的常见写法与优缺点
- Mapreduce——视频播放数据分类统计
- 逆波兰计算器的实现
- mysql 锁 事务
- mybatis 详解(八)------ 懒加载
- SFP光模块详解,看看有哪些是你不知道的!
- 八段代码彻底掌握 Promise
- 从入门到放弃,.net构建博客系统(一):系统构建篇
- 设置的文件名没用,下载文件名是前端页面文件名
- 欢迎使用CSDN-markdown编辑器
- java.io.EOFException 问题