(C语言)栈应用简易计算器实现
//利用栈实现简易计算器,进行包含+,-,*,/,(,)间的计算
#include<stdio.h>
#include<string.h>
#define MaxSize 100 typedef struct CharStack //字符栈
{char data[MaxSize];int top;
}cStack;typedef struct DoubleStack //数据栈
{double data[MaxSize];int top;
}dStack;int Isop(char ); //当前扫描元素优先级
int Inop(char ); //栈顶元素优先级 void Initc(cStack *); //初始化字符栈
int Pushc(cStack *,char); //字符栈压栈
char Gettopc(cStack *); //返回栈顶元素
char Popc(cStack *); //出栈 void Initd(dStack *); //初始化数据栈
int Pushd(dStack *,double); //数据压栈
double Popd(dStack *); //出栈 void Trans(char*s1,char*s2); //转化为后缀表达式 double Calculate(char *s2); //后缀表达式求值 int main()
{char s1[MaxSize]; //用于存储前缀表达式 char s2[MaxSize]; //用于存储转换后的表达式 printf("请输入表达式:");scanf("%s",s1);Trans(s1,s2); //处理字符串,并转化为后缀表达式,存放在s2中 printf("计算结果为: %f",Calculate(s2)); //后缀表达式求值 return 0;
}//初始化
void Initc(cStack *s1)
{s1->top=-1;
}//字符栈压栈 int Pushc(cStack *c1,char op){if(c1->top<MaxSize){c1->data[++c1->top]=op;return 1;}else return 0;
}//GET栈顶元素
char Gettopc(cStack *c1)
{return c1->data[c1->top];
}//字符栈出栈
char Popc(cStack *c1)
{return c1->data[c1->top--];
}//初始化数据栈
void Initd(dStack *d1)
{d1->top=-1;
}//数据栈压栈
int Pushd(dStack *d1,double data)
{if(d1->top<MaxSize){d1->data[++d1->top]=data;return 1;}else return 0;
}//数据栈出栈
double Popd(dStack *d1)
{return d1->data[d1->top--];
}int Isop(char op) //当前扫描运算符优先级
{switch(op){case '(': return 6;case '+': case '-': return 2;case '*': case '/': return 4;}
}
int Inop(char op) //当前扫描运算符优先级
{switch(op){case '(': return 1;case '+': case '-': return 3;case '*': case '/': return 5;}
}void Trans(char *s1,char *s2)
{int i=0;int j=0;int flag1=-1; //flag1为0表示上次输出为数字,flag1为1表示上次输出为字符int flag2=-1; //flag2为0表示上次扫描为数字,flag为1表示上次扫描为运算符,用于区分数字后加空格cStack st1; //暂放运算符 Initc(&st1);while(s1[i]!='\0') //处理负数 {if(s1[0]=='-') //第一位数字为负数时 {j=strlen(s1);while(j>0){s1[j+5]=s1[j];j--;}s1[j++]='(';s1[j++]='0';s1[j++]='-';s1[j++]='1';s1[j++]=')';s1[j]='*';}if(s1[i]=='('&&s1[i+1]=='-') //非第一位负数时 {j=strlen(s1);while(j>i+1){s1[j+5]=s1[j];j--;}s1[j++]='(';s1[j++]='0';s1[j++]='-';s1[j++]='1';s1[j++]=')';s1[j]='*';i=i+5;}i++;}i=0;j=0;while(s1[i]!='\0'){if(flag1==0&&flag2==1) //若上次的输出为数字,上次循环扫描为字符,则表示该数字串结束,则在数字后加空格区分 {s2[j++]=' ';flag1=1; }if(s1[i]>='0'&&s1[i]<='9'||s1[i]=='.'){s2[j++]=s1[i];flag2=0;flag1=0;}else if(s1[i]=='+'||s1[i]=='-'||s1[i]=='*'||s1[i]=='/'||s1[i]=='('){flag2=1;if(st1.top<0||Isop(s1[i])>Inop(Gettopc(&st1))){Pushc(&st1,s1[i]);}else{while(st1.top>=0&&Isop(s1[i])<Inop(Gettopc(&st1))) //当前扫描字符优先级不断与栈顶字符优先级比较,当前字符小于栈顶字符时退栈并输出 {s2[j++]=Popc(&st1);flag1=1;}if(st1.top<0||Isop(s1[i])>Inop(Gettopc(&st1))) //当前字符优先级大于栈顶优先级或栈空时当前字符压入字符栈内 {Pushc(&st1,s1[i]);}}}else if(s1[i]==')') {flag2=1;if(Gettopc(&st1)!='(') //若括号仅包含数字则没有输出运算符 {flag1=1;}while(Gettopc(&st1)!='('){s2[j++]=Popc(&st1);}Popc(&st1); //将'('出栈 }i++;}while(st1.top>=0) //将栈内剩余的运算符依次退栈输出 {s2[j++]=Popc(&st1);}s2[j]='\0';
}//表达式求值
double Calculate(char *s1)
{int i=0;int flag; //char类型转换为double类型数据标记 double data1,data2;double sum;dStack ds1;Initd(&ds1);while(s1[i]!='\0'){if(s1[i]=='+'||s1[i]=='-'||s1[i]=='*'||s1[i]=='/') //若为运算符获取栈顶两个元素进行计算 {data1=Popd(&ds1);data2=Popd(&ds1);if(s1[i]=='+') Pushd(&ds1,data2+data1);else if(s1[i]=='-') Pushd(&ds1,data2-data1);else if(s1[i]=='*') Pushd(&ds1,data2*data1);else if(s1[i]=='/') Pushd(&ds1,data2/data1);}else //为数据时转化为double类型压栈 {flag=0; //初始化为0为整数部分标记,1为小数部分标记 sum=0;double divider=1;while(s1[i]!=' '&&s1[i]!='+'&&s1[i]!='-'&&s1[i]!='*'&&s1[i]!='/'){if(s1[i]=='.') //若有小数点,进入小数转化模式 {flag=1;i++;continue;}if(flag==0){sum=sum*10+(double)(s1[i]-'0');}else{divider=divider*10;sum=sum+((double)(s1[i]-'0'))/divider;}i++;}if(s1[i]=='+'||s1[i]=='-'||s1[i]=='*'||s1[i]=='/') i--; //转化成功一个数据,若下个字符为运算符,则i--,回到当前运算的数据位置 Pushd(&ds1,sum);}i++; //i++准备下一个字符的转换 }return Popd(&ds1);
}
(C语言)栈应用简易计算器实现相关推荐
- 数据结构:栈实现简易计算器
文章目录 栈实现简易计算器 思路 代码实现 栈结构 运算方法 测试 栈实现简易计算器 之前的博客已经介绍了栈数据结构,栈有着数据先进后出的特点,因此用于实现简易计算器时相当方便.本博文中将介绍如何用栈 ...
- 十位数连加 c语言,用C语言编写一个简易计算器可实现加减乘除,连加连减,连乖连除....
用C语言编写一个简易计算器可实现加减乘除,连加连减,连乖连除. 用C语言编写一个简易计算器可实现加减乘除,连加连减,连乖连除. 人气:435 ℃时间:2020-04-10 06:55:13 优质解答 ...
- C语言实现控制台简易计算器(VC6.0可用)
一.项目介绍 C语言版简易计算器,包含几个小功能,包括基本运算.进制转换.一元二次方程,支持返回操作,整体源码比较精简,代码逻辑简单,扩展性强,非常适合新手了解和学习的小项目. 二.运行截图 导航菜单 ...
- C语言实现的简易计算器
实现简易计算器,可以处理两个操作数的加减乘除和取余. #include <cstdio>int main() {double num1,num2;char oper;printf(&quo ...
- evaluate函数使用无效_[Python实战]使用栈实现简易计算器
我们这次实现的命令行计算器,支持加减乘除.括号.浮点数.负数,以及查看历史和退出功能. 主要的思路:read - parse - print - loop. read 阶段是指读取用户在提示符(cal ...
- pnd1 c语言,c语言强化训练——简易计算器
一.设计要求 实现一个简单的计算器,要求可以求解表达式,支持基本的运算并有扩展能力和基本的容错能力 二.设计思路 程序需要定义两个工作栈,分别保存表达式计算过程中的运算符与运算数,通过一个优先级表来判 ...
- C语言编程实现简易计算器
输入格式为(%d %d %c)来进行简单的计算器编程 用switch来解决: #include<stdio.h>int main() { int date1,date2,result; c ...
- C语言如何制作简易计算器
#include <stdio.h> #include <string.h> /*指针函数制作计算器+-* */void menu() {printf("------ ...
- java栈实现简易计算器算法
问题描述: 对于任意字符串,包含+ - * /和括号, 求出该表达式的值 首先百度该问题,网上有不少答案,但是实际思考,发现,很多答案没有考虑完全,例如: -1+(-2)*3 遇到负号怎么 ...
最新文章
- ICCV2021|一种用于解决点云场景中同类对象分割的网络
- C#设计模式——适配器模式(Adapter Pattern)
- 16、ASP.NET MVC入门到精通——MVC过滤器
- 谁动了我的奶酪?--java实例初始化的顺序问题
- Springboot文件上传 百度ocr文字识别提取
- oracle数据库优化--基本概念
- nginx利用image_filter动态生成缩略图
- genymotion linux 32,Ubuntu Linux 32bit - 不是Genymotion虚拟设备
- CSDNmarkdown编辑器报错KaTeX parse error: \cr valid……
- 三维旋转四元数系列(4.四元数三维旋转表达)
- 在 GitHub 上收获 6519 颗 Star 的 Python 面试题资源,到底有多牛?
- Xcode9使用新体验
- Spring tool suite4 安装及配置
- 关于H3C-WAP712C AP的胖瘦切换说明
- CentOS 5.5安装 bluefish
- Asp.net mvc5开源项目超级冷笑话
- 机器学习实战——疫情数据分析与预测
- js二级联动,购物车
- 长沙银河计算机学校,长沙银河中等职业学校办学特色
- 将自动化测试推向极限