逆波兰计算器与中缀表达式向后缀表达式的转化实例
2016-04-30 23:55
549 查看
在本篇博文中,博主通过运用栈这一数据结构首先实现中缀表达式到后缀表达式的转换,而后通过结果运用逆波兰计算器得出计算结果。
具体代码如下:
可以简单的完成相应的计算。
具体代码如下:
#include <stdio.h> #include <ctype.h> #include <stdlib.h> using namespace std; typedef char ElemType; typedef enum{TRUE,FALSE} Status; #define STACK_INIT_SIZE 20 #define STACKINCREMENT 10 #define MAXBUFFER 10 typedef struct { ElemType *base; ElemType *top; int stackSize; }sqStack; void InitStack(sqStack *s) { s->base = (ElemType*)malloc(STACK_INIT_SIZE*sizeof(ElemType)); if (!s->base) { exit(0); } s->top = s->base; s->stackSize = STACK_INIT_SIZE; } Status Push(sqStack *s, ElemType e) { if (s->top - s->base >= s->stackSize) { s->base = (ElemType*)realloc(s->base, (s->stackSize + STACKINCREMENT)*sizeof(ElemType)); if (!s->base) { return FALSE; } s->top = s->base + s->stackSize; s->stackSize += STACKINCREMENT; } *(s->top) = e; s->top++; return TRUE; } Status Pop(sqStack *s, ElemType *e) { if (s->top == s->base) { return FALSE; } *e = *--(s->top); return TRUE; } int StackLen(sqStack s) { return (s.top - s.base); } //中缀表达式转换成后缀表达式 //规则:从左到右遍历中缀表达式的每个数字和符号,若是数字直接输出,若是 //符号,则判断其与栈顶的优先级,是右括号或优先级低于栈顶符号,则栈顶元素依次出栈并输出 //直到遇到左括号或栈空才将此符号入栈。 Status MidToEnd(sqStack s) { char c, e; scanf("%c", &c); while (c != '#') { while (c >= '0' && c <= '9') { //处理两位及以上的数字 printf("%c", c); scanf("%c", &c); if (c < '0' || c > '9') { //不是数字时 printf(" "); } } if (')' == c) { //为')'时需要出栈查找'(' Pop(&s, &e); while ('(' != e) { printf("%c ", e); Pop(&s, &e); if (!StackLen(s)) { //为空则说明没有'(' //printf("出错,缺少'('!\n"); //失败返回 return FALSE; } } } else if ('+' == c || '-' == c) { if (!StackLen(s)) { //为空直接压栈 Push(&s, c); } else { //不为空说明栈内还有符号,需要进行相应优先级的比较 do { Pop(&s, &e); if ('(' == e) { //若栈顶元素为'(',直接入栈 Push(&s, e); } else { //否则输出栈顶元素 printf("%c ", e); } } while (StackLen(s) && '(' != e); //当栈不为空且栈顶值不为'('一直输出 Push(&s, c); //将当前输入符号入栈 } } else if ('*' == c || '/' == c || '(' == c) { //直接入栈 Push(&s, c); } else if ('#' == c) { //由于在判断数字时多次输入,故无法保证是否输入'#',此处判断 //在上面判断也可 break; } else { //printf("出错,输入格式错误!\n"); //失败返回 return FALSE; } scanf("%c", &c); //继续输入 } while (StackLen(s)) { //若数字遍历完,则清空符号栈 Pop(&s, &e); printf("%c ", e); } //成功返回 return TRUE; } //逆波兰计算器 void Cal(sqStack s) { char c, d, e; char str[MAXBUFFER]; //缓冲Buffer int i = 0; scanf("%c", &c); while (c != '#') { while (isdigit(c) || c == '.')//用于过滤数字 { str[i++] = c; str[i] = '\0'; if (i >= MAXBUFFER) { printf("出错,输入的单个数字过大!\n"); return; } scanf("%c", &c); if (c == ' ')//数字输入结束 { d = atoi(str);//str-->int Push(&s, d); i = 0; break; } } switch (c) { case '+': Pop(&s, &d); Pop(&s, &e); Push(&s, d+e); break; case '-': Pop(&s, &d); Pop(&s, &e); Push(&s, e-d); break; case '*': Pop(&s, &d); Pop(&s, &e); Push(&s, d*e); break; case '/': Pop(&s, &d); Pop(&s, &e); if (d != 0) { Push(&s, e/d); } else { printf("\n出错,除数为零!\n"); return; } break; default: break; } scanf("%c", &c); } Pop(&s, &d); //得出结果 printf("最终计算结果为:%d\n",d); } int main() { sqStack s; InitStack(&s); printf("请输入中缀表达式,以#为结束标志:"); if (MidToEnd(s) == TRUE) { printf("\n上式为逆波兰表达式结果,请输入#结束输入:\n"); Cal(s); } else { printf("\n出错,输入格式错误!\n"); } return 0; }
可以简单的完成相应的计算。
相关文章推荐
- HDU_2295_Radar(DancingLinksX重复覆盖+二分)
- hiho第九十六周 数论五·欧拉函数
- js中的$和#
- eclipse中的server location灰色如何修改?
- 利用字符重复出现的次数,编写一个方法,实现基本的字符串压缩功能。比如,字符串“aabcccccaaa”经压缩会变成“a2b1c5a3”。若压缩后的字符串没有变短,则返回原先的字符串。
- ubuntu14.04 Nvidia 驱动和cuda安装(转)
- VO ,PO ,BO,QO, DAO ,POJO,概念
- HTML特殊编码转换
- 网站添加第三方登陆(PHP版)
- J2ee简介
- iOS9 新增特性(汇)
- Rafy 框架 - 使用 SqlTree 查询
- 时间下拉框(2)
- 请编写一个方法,将字符串中的空格全部替换为“%20”。假定该字符串有足够的空间存放新增的字符,并且知道字符串的真实长度(小于等于1000),同时保证字符串由大小写的英文字母组成
- Android之内部存储读取数据
- 观察者模式——应聘者和应聘公司的关系
- 70行Java代码BP神经网络
- 37-Invert Binary Tree
- dubbo入门实例代码
- redis数据结构--下