c 语言开发一个四则运算器,C++实现四则运算器(无括号)
本文实例为大家分享了C++实现无括号的四则运算器的具体代码,供大家参考,具体内容如下
完成度更高的带括号版本可以看C++实现四则运算器(带括号)
对于无括号的计算器,实现起来比较容易,下面让我们一步步实现。
举例
首先明确需要实现怎样的程序,对于无括号的计算器,大概做成这样就可以了:
52+34*3-4/2=
分析
对于例子中的表达式,由于乘除运算的优先级高于加减运算,我们不能直接从左到右进行。但四则运算的规则是从左到右,先乘除后加减,对于优先级相同的运算符还是可以从左到右运算的。
因此我们可以每读到一个运算符时,检查前一个运算符的优先级,如果前一个运算符的优先级与当前运算符相等或更高,那么我们便可以完成前一个运算符的计算;反之,则不进行运算。这样一来就需要将之前的运算符以及运算符左右的数保存起来,由于我们每次都是取前一个运算符,符合后进先出的条件,故可以选择栈来存储数据和符号。最好将数据和符号分开存储,这里为了简便(整数栈即可存储数字也可存储字符),只实现整数的四则运算,若需要浮点数的运算,稍加修改即可。
首先,实现一个栈的类,或者直接使用STL
//Stack.h
#ifndef STACK_H
#define STACK_H
#include
class stack_int
{
private:
int* bottom; //栈底
int* top; //栈顶
unsigned int capacity;//栈容量
unsigned int size; //栈大小
public:
stack_int() :bottom(new int[11]), top(bottom), capacity(10), size(0) {};
stack_int(unsigned int capacity) :bottom(new int[capacity+1]),top(bottom), capacity(capacity),size(0){};
int operator[](unsigned int i) const
{
return *(bottom + i);
}
bool isEmpty()const { return bottom == top; }
bool isFull()const { return size == capacity-1; }
unsigned int getsize()const { return size; }
unsigned int getcapacity()const { return capacity; }
int gettop()const
{
if (!isEmpty())
return *(top - 1);
else
return -1;
}
void settop(int i)
{
if (!isEmpty())
{
*(top - 1) = i;
}
}
void push(int i)
{
if ((top - bottom)
{
*top = i;
top++;
size++;
}
else
{
std::cout << "stack full!" << std::endl;
stack_expansion();
push(i);
}
}
int pop(int &val)
{//返回值为1则栈未空,返回值为0则栈已空无法出栈
if (top > bottom)
{
top--;
size--;
val = *top;
return 1;
}
else
{
std::cout << "stack empty!" << std::endl;
return NULL;
}
}
private:
void stack_expansion()
{//栈扩容
std::cout << "正在扩容中..." << std::endl;
int newcapacity = 2 * capacity + 1;
int* newbottom = new int[newcapacity + 1];
int* newtop = newbottom;
for (int i = 0; i < size; ++i)
{
*newtop = *bottom;
newtop++;
bottom++;
}
bottom = newbottom;
top = newtop;
capacity = newcapacity;
}
};
#endif
然后在我们的主程序中利用栈来分析四则运算的规律(源代码如下)
//Main.cpp
#include"stack.h"
#include
using namespace std;
bool is_digit(char i)
{//是数字
if (i == '1' || i == '2' || i == '3' || i == '4' || i == '5' || i == '6' || i == '7' || i == '8' || i == '9' || i == '0')
return true;
else return false;
}
bool is_operator(char i)
{//是运算符
if (i == '+' || i == '-' || i == '*' || i == '/' ||i=='=')
return true;
else return false;
}
bool get_priority(char pre,char cur)
{//获取两个符号间的优先级,pre为靠前的字符,cur为靠后的字符
if ((pre == '+' || pre == '-') && (cur == '*' || cur == '/'))
return false;
else
return true;
}
int do_operation(int lnum, char ope, int rnum)
{
if (ope == '+')
return lnum + rnum;
if (ope == '-')
return lnum - rnum;
if (ope == '*')
return lnum * rnum;
if (ope == '/')
return lnum / rnum;
}
/*
1+2*3=
1+5*4-345+36/6*4+145*4*5-52=
*/
int main()
{
stack_int s;
stack_int num_stack;//数据栈
stack_int ope_stack;//符号栈
char current_char;
current_char = getchar();
bool overflag = false;
while (overflag!=true)
{//未遇到=号时不断进行四则运算
if (is_digit(current_char))
{//遇到数字符号则将完整的数解析出来并保存于栈中
int num = 0;
num = current_char - '0';//符号转数字
current_char = getchar();//获取下一个字符
while (is_digit(current_char))
{
num = num * 10+(current_char-'0');
current_char = getchar();
}
num_stack.push(num);
//cout <
}
if (current_char == ' ')
{//空格则继续
current_char = getchar();
continue;
}
if (is_operator(current_char))
{//遇到运算符则将运算符保存于运算符栈中
int ope = '?';
//如果当前符号栈非空,则不断根据优先级决定是否进行一次运算
while((!ope_stack.isEmpty())&&(get_priority((char)ope_stack.gettop(),current_char)))
{//如果前一个运算符优先级更高
ope_stack.pop(ope);
//cout << "找到了前一个运算符为: " << (char)ope << endl;
int lnum, rnum;
//符号栈非空时,数据栈应该至少有两个数,否则出错
if (num_stack.isEmpty())
{
cout << "数据栈缺失两个元素,解析失败!" << endl;
overflag = true;
break;
}
num_stack.pop(rnum);
if (num_stack.isEmpty())
{
cout << "数据栈缺失一个元素,解析失败!" << endl;
overflag = true;
break;
}
num_stack.pop(lnum);
lnum = do_operation(lnum, (char)ope, rnum);//进行运算
num_stack.push(lnum);
}
if (current_char == '=')
{//如果解析到=号了,解析完成
overflag = true;
break;
}
ope_stack.push(current_char);
current_char = getchar();
}
}
for (int i = 0; i < num_stack.getsize(); ++i)
cout << num_stack[i] << "\t";
cout << endl;
for (int i = 0; i < ope_stack.getsize(); ++i)
cout << (char)ope_stack[i] << "\t";
return 0;
}
这里需要注意一些问题,首先,由于整数可能是多位数,因此在遇到一个数字符号时,我们可以通过循环将后面几位全部找出,并将符号转化为真正的数值。
第二个问题就是有时候会出现表达式解析到等号了,却有很多数没进行运算,解决这个问题的方法就是在
if (is_operator(current_char))
中使用while循环,并将循环条件设置为栈非空且栈顶运算符优先级高于当前读入的运算符(前提是=的优先级小于任何运算符)
while((!ope_stack.isEmpty())&&(get_priority((char)ope_stack.gettop(),current_char)))
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
c 语言开发一个四则运算器,C++实现四则运算器(无括号)相关推荐
- 用Go语言开发一个编程语言
用Go语言开发一个编程语言 最近小弟业余时间闲来无事,所以就尝试一下自己开发一个轻量级的解释型语言. 出于学习的目的,我目前已经利用业余时间开发了一个多月,目前实现了变量声明,内置函数调用.自定义函数 ...
- c语言开发一个学生成绩统计程序,用C语言实现成绩统计程序的设计课程设计报告.doc...
武汉理工大学华夏学院 课程设计报告书 课程名称: 数据结构课程设计 题 目:用C语言实现成绩统计程序的设计 系 名: 信息工程系 专业班级: 计算机1121 姓 名: 学 号: 指导教师: 20**年 ...
- c语言bt下载程序,用C语言开发一个BT下载软件(一) ------ BitTorrent协议 -1
BitTorrent(简称BT)是一个文件分发协议,每个下载者在下载的同时不断地向其他下载者上传已下载的数据.它是属于一个应用层的协议. 基于BT协议的文件分发系统由以下几个实体构成: 一个web服务 ...
- 用C语言开发一个BT下载软件(一) ------ BitTorrent协议 -1
BitTorrent(简称BT)是一个文件分发协议,每个下载者在下载的同时不断地向其他下载者上传已下载的数据.它是属于一个应用层的协议. 基于BT协议的文件分发系统由以下几个实体构成: 一个web服务 ...
- java代下订单管理模块_用java语言开发一个订单管理系统
管理员登陆窗体(LoginForm):窗体中包含"管理员姓名","管理员密码",按钮:"确定","取消"操作主窗体(Ma ...
- 用C语言开发一个BT下载软件 (二) ------ 算法和策略
流水线作业 当客户端向peer发送数据请求时(即发送request消息),一次请求多个slice(即在一个数据包中发送多个request消息请求多个slice).peer发送完一个slice后接着发送 ...
- 用C语言开发一个BT下载软件 (三) ------ 系统结构设计
整个系统各个模块功能如下图所示: 种子解析:负责解析种子文件,从中获取Tracker服务器的地址,待下载文件的文件名和长度,piece长度,各个piece的hash值. 连接Tracker:根据HTT ...
- c语言 编写小学生100以内四则运算数学测试游戏,运用C语言开发一个“小学生算术四则运算测试系统”。...
该系统是让计算机充当一位给小学生布置作业的算术老师,为学生出题并阅卷.该系统要求实现下列功能: ①为小学生出题(分别进行+.-.*./等不同运算). ②学生做题后,进行评阅.学生每做一题后,评阅给出& ...
- c语言开发一个绘画,c语言也能画画
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #define PI 3.14159265 LRESULT CALLBACK WindowProcedure ( HW ...
最新文章
- 安装了libevent和memcached之后却发现在执行的时候出现了 error while loading shared libraries问题...
- ubuntu tacacs 服务器安装启动
- 开源软件加密授权方案_身份验证和授权作为开源解决方案服务
- 64位系统下,一个32位的程序究竟可以申请到多少内存,4GB还是更多
- springboot 上传图片大小_springboot 文件上传大小配置的方法
- Nginx 负载均衡策略之加权轮询分析
- 普通人如何月入10万
- Web UI设计师的CSS优化工具 25+
- Hibernate 一对多连接表单向关联
- 凸优化第二章凸集 2.4 广义不等式
- Typora入门(中文版)
- 黑客无孔不入!网络安全成五角大楼重中之重
- AIX添加ASM的裸盘
- USBCAN 、便携式 CAN 分析仪 、CAN卡
- ArcGIS操作实例视频教程38讲全集(转)
- xmlDocument是什么?
- 【正点原子FPGA连载】 第二十三章 EEPROM读写测试实验-摘自【正点原子】领航者ZYNQ之FPGA开发指南_V2.0
- Linux 中的 -rwxr-xr-x 权限代表什么意思 Linux 中的权限
- 战神引擎去右上角信息
- 阿里云飞天计划体验-阿里云开发者社区
热门文章
- 编译型与解释型、动态语言与静态语言、强类型语言与弱类型语言概念辨析
- mysql执行语句后回退_MySQL命令学习笔记(八)
- php读取ds18b20,DS18B20_单总线协议
- 数据归一化处理方法_科研常用的实验数据分析与处理方法
- Spring Cloud Zuul网关 Filter、熔断、重试、高可用的使用方式。
- 基于百度语音识别API的Python语音识别小程序
- Winodows10 安全登录(Administrator账户与Microsoft Account关联
- 索引(转载自百度百科)
- 关于静态库、动态库的区别汇总
- 【Microsoft Azure学习之旅】测试消息队列(Service Bus Queue)是否会丢消息