C++使用栈实现简易计算器(支持括号)

使用C++实现,使用系统自带stac

  1. 支持括号处理
  2. 支持小数计算
  3. 支持表达式有效性检查
  4. 支持多轮输入。

运行结果示例:

代码:

#include <iostream>
#include <stack>
#include <string>
using namespace std;//判断是否是数字字符
int isNumber(char c)
{if(c>='0' && c<='9')return 1;elsereturn 0;
}//判断字符是否是操作符,这里仅支持+、-、*、/
int isOperator(char c)
{if(c=='+' || c=='-' || c=='*' || c=='/')return 1;elsereturn 0;
}//获取操作符的优先级
int priority(char op)
{if(op=='+' || op=='-')return 1;else if(op=='*' || op=='/')return 2;else if(op=='(')return 0;return 0;
}//有效性判断1:判断是否缺操作符,缺操作符返回1,否则返回0
int isLessOperator(char* p)
{int i = 0,j,k;//考虑一下几种情况://1.数字之间没有操作符,例如 2 3 + 4//2.(前面是数字,例如 2(2+3),这里不支持省略乘号//3.)后面是数字,例如 (2+3)3,这里不支持省略乘号while(p[i]!='\0'){if(p[i]==' '){j = i-1; while(j>=0 && p[j]==' ') j--; //往前遍历,直到遇到非空格k = i+1;while(p[k]==' ') k++;//往后遍历,直到遇到非空格if(j>=0 && isNumber(p[j]) && isNumber(p[k])) //空格前后都是数字return 1; //说明缺少操作符,返回1}else if(p[i]=='('){j = i-1;while(j>=0){if(isOperator(p[j]) || p[j]=='(')break;else if(p[j]==' ')//跳过空格{j--;continue;}else if(isNumber(p[j]))return 1;else if(p[j]==')')//出现 )(这种情况,((这种情况在这里不讨论,会在括号匹配函数中处理return 1; elsereturn 2; //这里可能出现非数字、非操作符、非括号}}else if(p[i]==')'){j = i+1;while(p[j]!='\0'){if(isNumber(p[j]))return 1;else if(isOperator(p[j]))break;else if(p[j]==' '){j++;continue;}else if(p[j]==')')break;else if(p[j]=='(')return 1;elsereturn 2; //出现非数字、非操作符、非括号}}i++;}return 0;
}
//有效性判断2:判断括号是否匹配,匹配返回1,否则返回0
int isComplete(char* p)
{int i=0;int nmb = 0; //(的个数while(p[i]!='\0'){if(p[i]=='(')nmb++;else if(p[i]==')')nmb--;if(nmb<0)return 0;i++;}if(nmb != 0)return 0;return 1;
}
//有效性判断3:是否是连续操作符(负数操作时必须用括号括起来),出现连续操作符返回1,否则返回0
int isMoreOperator(char* p)
{int i=0,j;while(p[i]!='\0'){if(isOperator(p[i])){j=i-1; //向前判断while(j>=0){if(p[j]==' '){j++;continue;}else if(isOperator(p[j]))return 1;else if(isNumber(p[j]))break;else if(p[j]==')'||p[j]=='(') //是括号break;elsereturn 2; //非数字、非空格、非括号、非操作符外的其他符号}}i++;}return 0; //
}//有效性判断4:判断是否是空括号,如2+()+3
int isEmptyKh(char* p)
{int i=0,j;while(p[i]!='\0'){if(p[i]==')'){j= i-1;while(j>=0){if(p[j]=='(')return 1;else if(p[j]==' ')j--;elsebreak;}}i++;}return 0;
}
//判断表达式的有效性
int isValid(char* p)
{int res = 1,t;int len = strlen(p);if(p[len-1]=='=' || p[len-1]=='#') //以=或者#结尾p[len-1]=0;t = isLessOperator(p);if(t == 1){printf("缺少操作符!\n");res = 0;}else if(t == 2){printf("出现符数字、空格、操作符、括号之外的符号\n");res = 0;}t = isComplete(p);if(t==0){printf("括号不匹配\n");res = 0;}t = isMoreOperator(p);if(t == 1){printf("有多个连续运算符\n");res = 0;}else if(t==2){printf("出现符数字、空格、操作符、括号之外的符号\n");res = 0;}t = isEmptyKh(p);if(t==1){printf("有空括号\n");res = 0;}return res;
}
//执行某个运算
int getResult(double a,double b,char c,double *v)
{if(c=='+'){*v = a+b;return 1;}else if(c=='-'){*v = a-b;return 1;}else if(c=='*'){*v = a*b;return 1;}else if(c=='/'){if(b==0)return 0;*v = a/b;return 1;}return 0;
}
//计算
int Caculate(char* p,double *res)
{stack<double> data; //数据stack<char> oper;  //操作符int i=0;double a,b,c;char op1,op2;double mi=1; while(p[i]!='\0'){if(isNumber(p[i])) //当前字符是数字,则读取后续的数字,并入栈{a = p[i]-'0';i++;//继续读取后面的数字while(isNumber(p[i])){a = a*10+(p[i]-'0');i++;}if(p[i]=='.'){i++;//处理小数部分mi = 10;while(isNumber(p[i])){a = a + (p[i]-'0')/mi;mi*=10;i++;}}data.push(a);//数据入栈}else if(isOperator(p[i])) //是运算符{if(oper.empty()){oper.push(p[i]);i++;}else{op1 = oper.top(); //获取栈顶运算符//比较op1和p[i]的优先级,如果op1的优先级高于p[i],则数据出栈并进行计算if(priority(op1) >= priority(p[i])){b = data.top(); //后操作数data.pop();a = data.top(); //前操作数data.pop();oper.pop(); //运算符出栈if(getResult(a,b,op1,&c)){if(!oper.empty()){op2 = oper.top();if(op2=='-' && c<0){oper.pop();oper.push('+');data.push(-c); //减负数等价于加正数oper.push(p[i]);}else{data.push(c); //新数据入栈oper.push(p[i]); //操作符入栈}}else{data.push(c); //新数据入栈oper.push(p[i]); //操作符入栈}i++;}else{printf("除数为0\n");return 0;}}else{oper.push(p[i]); //操作符入栈i++;}}}else if(p[i]=='('){oper.push(p[i]); //入栈i++;}else if(p[i]==')') //出栈计算{op1 = oper.top();if(op1=='('){oper.pop();//(出栈i++;}else {b = data.top(); //获取栈顶元素,该数为后操作数data.pop();a = data.top();data.pop();oper.pop(); //运算符出栈if(getResult(a,b,op1,&c)){if(!oper.empty()){op2 = oper.top();if(op2=='-' && c< 0){oper.pop();oper.push('+');data.push(-c);}elsedata.push(c);}elsedata.push(c);//新数据入栈}else{printf("除数为0\n");return 0;}}} else if(p[i]==' ')i++;}//处理栈内数据while(!oper.empty()){b = data.top();data.pop();a = data.top();data.pop();op1 = oper.top();oper.pop();if(getResult(a,b,op1,&c)){if(!oper.empty()){op2 = oper.top();if(op2 == '-' && c< 0){oper.pop();oper.push('+');data.push(-c);}elsedata.push(c);}elsedata.push(c);}else{printf("除数为0\n");return 0;}}if(data.size() !=1 ){printf("error\n");return 0;}*res = data.top();data.pop();return 1;
}int main()
{char buf[100]={0};int op;while(1){printf("输入表达式:\n");cin.getline(buf,100); //读取一行double res = 0;if(isValid(buf)){if(Caculate(buf,&res))printf("%g\n",res);}printf("是否继续(1:继续   2:退出):");scanf("%d",&op);if(op == 2)break;getchar(); //吸收回车符}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/177765.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决pycharm中,远程服务器上文件找不到的问题

一、问题描述 pycharm中&#xff0c;当我们连接到远程服务器上时。编译器中出现报错问题&#xff1a; cant open file /tmp/OV2IRamaar/test.py: [Errno 2] No such file or directory 第二节是原理解释&#xff0c;第三节是解决方法。 二、原理解释 实际上这是由于我们没有设置…

5.5 TCP报文段的首部格式

思维导图&#xff1a; 5.5 TCP报文段的首部格式 基本概念 TCP报文段&#xff1a;包含首部和数据两部分&#xff0c;首部至少20字节。作用&#xff1a;首部字段定义了TCP的功能和行为。长度&#xff1a;首部长度可变&#xff0c;基础首部20字节&#xff0c;可添加选项。 首部…

Openssl数据安全传输平台019:外联接口类的封装以及动态库的制作 - Bug未解决,感觉不是代码的问题

文章目录 1 外联接口1.1 接口类的封装1.2 共享内存与配置文件 2 json格式配置文件的定义2.1 共享内存中存储的节点结构2.2 服务器端配置文件2.3 客户端配置文件2.4 改进配置文件 3 共享内存类修改4 将接口打包成库(静态/动态)4.1 相关的指令4.1.1 静态库4.1.2 动态库 4.2 外联接…

【地理位置识别】IP归属地应用的特点

IP归属地应用是一类用于确定特定IP地址的地理位置信息&#xff08;通常是城市、地区或国家&#xff09;的工具和服务。以下是IP归属地应用的几个主要特点&#xff1a; 地理位置识别&#xff1a; IP归属地应用主要用于确定IP地址的地理位置。这可以帮助组织更好地了解其网站访问…

Physics2DPlugin3加载后会跳转gsap官网解决

因工作需要使用Physics2DPlugin3库&#xff0c;目标效果 加载他里面的在线js&#xff0c;使用效果正常&#xff0c;但是几秒会跳转官网&#xff0c;我们app内部、浏览器都会这样。 于是研究js代码&#xff0c;发现里面有setTimeout跳转。 删掉就好了 分享我改好的文件&#x…

全球地表动态水体产品(数据集V2.0)(2000-2020年/8天/250米)

摘要 全球地表动态水体产品(8天/250米)GSWED(Global Surface Water Extent Dataset)由中国科学院空天信息创新研究院湿地与环境遥感研究团队制作而成。本套数据集是基于MODIS数据构建了一套全球地表水体NDVI阈值时空参数集,在此基础上使用遥感大数据云平台进行研发的,使用G…

【Excel密码】四个方法,设置excel表格只读模式

Excel文件想要设置成只读模式&#xff0c;其实很简单&#xff0c;今天给大家分享四个excel设置只读模式的方法。 方法一&#xff1a;文件属性 右键点击文件&#xff0c;查看文件属性&#xff0c;在属性界面&#xff0c;勾选上只读属性就可以了。 方法二&#xff1a;始终以只读…

左移测试,如何确保安全合规还能实现高度自动化?

「云原生安全既是一种全新安全理念&#xff0c;也是实现云战略的前提。 基于蚂蚁集团内部多年实践&#xff0c;云原生PaaS平台SOFAStack发布完整的软件供应链安全产品及解决方案&#xff0c;包括静态代码扫描Pinpoint&#xff0c;软件成分分析SCA&#xff0c;交互式安全测试IA…

【密评】商用密码应用安全性评估从业人员考核题库(十七)

商用密码应用安全性评估从业人员考核题库&#xff08;十七&#xff09; 国密局给的参考题库5000道只是基础题&#xff0c;后续更新完5000还会继续更其他高质量题库&#xff0c;持续学习&#xff0c;共同进步。 4001 多项选择题 网络和通信安全层面的通信主体一般包括哪些&…

uni-app 微信小程序 搜索关键字后 结果中的关键字变色

如图&#xff1a;想实现搜索关键字&#xff0c;搜索到的内容中把包含的此字变为蓝色。 实现方式如下&#xff1a;此方式是uniapp开发运行到微信小程序的代码。 第一种方法&#xff1a;小程序自己实现 1.布局写法 *[HTML]: 没有使用花括号渲染,所以需要 $options.filters 来…

平面波向球面波的展开

平面波向球面波的展开是一个极其重要的话题 手稿放在文章的结尾处 勒让德展开 citation 1: 我们整理一下&#xff0c;对exp(x)做泰勒展开&#xff0c;得 citation 2: 我们先把精力集中到解决这个积分上去 反复利用分部积分 考虑到奇偶性问题 当且仅当时积分不为零现在做变换 …

红队专题-从零开始VC++C/S远程控制软件RAT-MFC-远程桌面屏幕监控

红队专题 招募六边形战士队员[24]屏幕监控-(1)屏幕查看与控制技术的讲解图像压缩算法图像数据转换其他 [25]---屏幕监控(2)查看屏幕的实现添加 CScreen类获取图像声明变量stdafx.h 头文件处理发送函数 7.1 屏幕抓图显示创建对话框工程&#xff0c;拉入图片显示控件修改控件为位…

解析mfc100u.dll文件丢失的修复方法,快速解决mfc100u.dll问题

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中最常见的就是“缺少某个文件”的错误。最近&#xff0c;我也遇到了一个这样的问题&#xff0c;那就是“mfc100u.dll丢失”。这个问题可能会导致某些应用程序无法正常运行&#xff0c;给我们带来困扰。…

精品Python空巢老人志愿服务平台慈善捐赠活动报名

《[含文档PPT源码等]精品基于Python的空巢老人志愿服务平台》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;python 使用框架&#xff1a;Django 前端技术&#…

PicoDiagnostics (NVH设备软件)-电脑无法识别示波器(安装驱动)

有些用户第一次使用示波器时&#xff08;或者更换电脑使用示波器时&#xff09;&#xff0c;发现电脑识别不了示波器&#xff0c;出现此类问题&#xff0c;可以根据下述方法进行解决。 我们先来看看软件识别到示波器的状态&#xff1a; PS7版本的软件中&#xff0c;可以点击软件…

[Linux 基础] Linux使用git上传gitee三板斧

文章目录 1、使用git1.1 安装git1.2 在Gitee上创建项目1.2.1 使用Gitee创建项目1.2.2 上传本地代码到远端仓库 1.3 git上传三板斧1.3.1 三板斧第一招&#xff1a;git add1.3.2 三板斧第二招&#xff1a;git commit1.3.3 三板斧第三招&#xff1a;git push 1、使用git 1.1 安装…

神经网络的解释方法之CAM、Grad-CAM、Grad-CAM++、LayerCAM

原理优点缺点GAP将多维特征映射降维为一个固定长度的特征向量①减少了模型的参数量&#xff1b;②保留更多的空间位置信息&#xff1b;③可并行计算&#xff0c;计算效率高&#xff1b;④具有一定程度的不变性①可能导致信息的损失&#xff1b;②忽略不同尺度的空间信息CAM利用…

本地创建一个虚拟机,并且能够连接到外网

1、从官网下载虚拟机 2、详细的安装教程 点击这里 其中这里的获取&#xff0c;我们店自动IP地址获取就行了&#xff0c;DNS也是自动获取就行了。 4、注意事项 4.1 linux命令:vim: command not found无法使用解决方案, 点击这里

Flask Shell 操作 SQLite

一、前言 这段时间在玩Flask Web&#xff0c;发现用Flask Shell去操作SQLite还是比较方便的。今天简单地介绍一下。 二、SQLite SQLite是一种嵌入式数据库&#xff0c;它的数据库就是一个文件&#xff0c;处理速度快&#xff0c;经常被集成在各种应用程序中&#xff0c;在IO…

记录rider编辑器快速文档 中英文显示的问题

起初是不同的项目里快速文档一个项目显示中文 一个项目显示英文 搞了很久不知道哪里的原因 偶然灵机一动,点开了下面docs.microsoft.com的地址进去一看 发现一个是4.6的文档 一个是4.6.1的文档 所以去项目属性里 切换了framework的版本. 然后汉化就好了 纯属强迫症,而且…