巧妙利用栈实现计算器
来源:互联网 发布:js 网页mp4播放器代码 编辑:程序博客网 时间:2024/05/03 05:32
首先我们实现一个计算器,用户所输入的为中缀表达式,这是通用的算术公式的表达方法,但是有一个缺点就是不容易被计算机所理解。所以,有了所谓的后缀表达式!
后缀表达式:不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则,如:(2 + 1) * 3 , 即2 1 + 3 *
然后咱们通过栈来实现这个计算器的功能。
在这里中缀表达式转后缀表达式我主要采用了两个数组和一个栈实现,这个栈首先是来保存运算符,通过数组和栈配合实现后缀表达式,然后为了得到结果,使用了strtok()函数,这个函数用来字符串分割,最终可以得到结果。
详细代码如下:
cal.h
#define _CRT_SECURE_NO_WARNINGS 1#ifndef __CAL_H__#define __CAL_H__//利用顺序栈实现计算器#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAXSIZE 50typedef int SElemType;//定义一个顺序存储栈typedef struct{ SElemType data[MAXSIZE]; int top;}SqStack;int To_PostFix(char *infix, char *postfix);int Calculator(char *postfix, int *result);#endif // !__CAL_H__
cal.c
#define _CRT_SECURE_NO_WARNINGS 1#include"cal.h"/*******************栈的基本操作********************************/int init_stack(SqStack *s){ s->top = -1; return 1;}int clear_stack(SqStack *s){ s->top = -1; return 1;}int stack_empty(SqStack s){ if (s.top == -1) return 1; else return 0;}int stack_length(SqStack *s){ return s->top + 1;}int push(SqStack *s, SElemType e){ if (s->top == MAXSIZE - 1) return 0; s->top++; s->data[s->top] = e; return 1;}int pop(SqStack *s, SElemType *e){ if (s->top == -1) return 0; *e = s->data[s->top]; s->top--; return 1;}/*******************中序表达式转换为后续表达式********************************/int To_PostFix(char *infix, char *postfix){ SqStack s; int e = 0; int i = 0, j = 0; int flag = 0; if (init_stack(&s) != 1) //判断栈是否为空, return 0; while (infix[i] != '\0') //说明栈中有元素。 { while (infix[i] >= '0' && infix[i] <= '9') //如果是数字则输出 { if (flag) //考虑负数的情况 { flag = 0; postfix[j++] = '-'; } postfix[j++] = infix[i];//让存放后缀表达式的数组存放字符 i++; if (infix[i]<'0' || infix[i]>'9') //判断是否为操作符,如果是,让后缀表达式中存放一个' ' postfix[j++] = ' '; } if (infix[i] == ')' ) //如果是关于括号的符号,则进行栈操作 { pop(&s, &e); while (e != '(' ) { postfix[j++] = e; postfix[j++] = ' '; pop(&s, &e); } } else if (infix[i] == '+' || infix[i] == '-') //对于同运算级的+和-操作 { if (infix[i] == '-' && (i == 0 || (i != 0 && (infix[i - 1]<'0' || infix[i - 1]>'9')))) //当'-'号处于第一位,或前面是符号时,为负号标志 flag = 1; else if (stack_empty(s)) push(&s, infix[i]); else { do { pop(&s, &e); if (e == '(' ) push(&s, e); else { postfix[j++] = e; postfix[j++] = ' '; } } while (!stack_empty(s) && e != '(' ); push(&s, infix[i]); } } else if (infix[i] == '*' || infix[i] == '/' || infix[i] == '(' )//对于乘除以及括号的开始进行压栈 push(&s, infix[i]); else if (infix[i] == '\0') break; else return 0; i++; } while (!stack_empty(s)) { pop(&s, &e); postfix[j++] = e; postfix[j++] = ' '; } clear_stack(&s); return 1;}/*******************根据后续表达式计算结果********************************/int Calculator(char *postfix, int *result){ SqStack s; char *op; //存放后缀表达式中的每个因数或运算符 char *buf = postfix; //声明bufhe saveptr两个变量,是strtok_r函数的需要。 char *saveptr = NULL; int d, e, f; if (init_stack(&s) != 1) return 0; while ((op = strtok(buf, " ")) != NULL)//利用字符串分割函数 { buf = NULL; //把指针置空 switch (op[0]) { case '+': pop(&s, &d); pop(&s, &e); f = d + e; push(&s, f); break; case '-': if (op[1] >= '0' && op[1] <= '9') //是负号而不是减号 { d = atoi(op); push(&s, d); break; } pop(&s, &d); pop(&s, &e); f = e - d; push(&s, f); break; case '*': pop(&s, &d); pop(&s, &e); f = e*d; push(&s, f); break; case '/': pop(&s, &d); pop(&s, &e); f = e / d; push(&s, f); break; default: //考虑数字的情况,进行atoi函数进行转化 d = atoi(op); push(&s, d); //进行压栈 break; } } pop(&s, result); clear_stack(&s); return 0;}
test.c
#define _CRT_SECURE_NO_WARNINGS 1#include"cal.h"void Test(){ char infix[MAXSIZE] = { 0 }; char postfix[MAXSIZE] = { 0 }; int result = 0; printf("请输入一个中缀表达式:\n"); scanf("%s", infix); fflush(stdin); To_PostFix(infix, postfix); printf("转换得到的后缀表达式是:\n"); printf("%s\n", postfix); Calculator(postfix, &result); printf("最后得到的结果:\n"); printf("%d\n", result);}int main(){ Test(); system("pause"); return 0;}
3 0
- 巧妙利用栈实现计算器
- 1/18巧妙利用栈实现计算器
- 利用递归巧妙实现组合
- C语言利用栈实现Polish计算器
- 作业:C++利用栈实现的计算器
- 利用栈来实现的计算器
- 巧妙利用ascii函数实现字符串匹配
- 利用模板巧妙实现二级接口
- 利用CountDownTimer巧妙地实现倒计时功能
- 利用搜索引擎实现命令行计算器
- 利用栈实现简单计算器的例子(Calculator)
- 利用栈Stack实现计算器实验设计(C++)
- 巧妙的利用C++的特性实现Profiling
- 巧妙利用DZ自有功能实现豆丁网在线文档功能
- 利用CSS3特性巧妙实现漂亮的DIV箭头
- 利用死循环巧妙实现,回车对话框不关闭
- PHP巧妙利用位运算实现网站权限管理
- 利用CSS3特性巧妙实现漂亮的DIV箭头
- Sql Server 2008——查询(1)——计算列
- Web API应用架构在Winform混合框架中的应用(5)--系统级别字典和公司级别字典并存的处理方式
- _weak typeof(self) weakSelf = self
- Hibernate-连接查询
- 自由落体球
- 巧妙利用栈实现计算器
- Servlet 生命周期、工作原理
- Android仿qq健康效果
- 数据库表的级联删除与更新
- 关于软件开发大赛
- OpenCV中ROI 总结
- 块设备驱动架构分析
- sparkstreaming统计一段时间内的热搜词
- Java 匿名内部类