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)))

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

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

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

相关文章

iOS开发之解决系统数字键盘无文字时delete键无法监听的技巧

最近在做用户登录获取验证码时添加图形验证码功能&#xff0c;就是只有正确输入图形验证码才能收到后台发送的短信验证码。效果如下&#xff1a; 看起来虽然是个小功能&#xff0c;但是实际操作起来&#xff0c;会发现苹果给我们留下的坑&#xff0c;当然更多的是自己给自己挖的…

c ++查找字符串_C ++结构| 查找输出程序| 套装1

c 查找字符串Program 1: 程序1&#xff1a; #include <iostream>#include <math.h>using namespace std;struct st {int A NULL;int B abs(EOF EOF);} S;int main(){cout << S.A << " " << S.B;return 0;}Output: 输出&#xff1a…

二级c语言加油,二级C语言 备考指南及常见问题(2013版)

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼3、关于上机操作部分的复习最好买一本上机题库方面的教材&#xff0c;或打印、阅读南开百题之类的电子文档。配合上机模拟软件(无纸化考试软件)&#xff0c;上机练习是必须的。上机软件一般有100套题多一点&#xff0c;每套有程序填…

开放定址散列表

再散列之后散列函数要重新计算。 // kaifangliaobiao.cpp : 定义控制台应用程序的入口点。 //使用平方探测解决冲突问题时&#xff0c;散列表至少空一半时&#xff0c;总能插入一个新的元素#include "stdafx.h" #include<iostream> using namespace std;#ifnde…

合并两个链表数据结构c语言,合并两个链表.

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include #define N1 10#define N2 10struct list{int date ;struct list *next;};main(){struct list *p1,*p2,*p3,*p4,*head,*head1,*head2,*p;int n0;head1head2NULL;p1p2(struct list *)malloc(sizeof(struct list));p1->da…

c ++查找字符串_C ++结构| 查找输出程序| 套装2

c 查找字符串Program 1: 程序1&#xff1a; #include <iostream>using namespace std;int main(){typedef struct{int A;char* STR;} S;S ob { 10, "india" };S* ptr;ptr &ob;cout << ptr->A << " " << ptr->STR[2];…

连接fiddler后手机无法显示无网络

升级了fiddler到4.6版本&#xff0c;手机设置代理后提示无网络&#xff0c;试试以下解决方法&#xff1a; 1.fiddler升级后对应的.net framework也要升级&#xff0c;安装最新的.net framework 4.6&#xff0c;升级安装后&#xff0c;可以正确抓包啦 2.如果上述方法无效&#x…

android 人脸解锁 锁屏动画,人脸保护锁(人脸识别锁屏)

这是一款十分炫酷的锁屏工具&#xff0c;还记得电影中的特工所用的人脸识别锁吗&#xff1f;这款应用也能让你过过瘾&#xff01;人脸识别锁屏安卓版是一款用人脸做密码来打开手机屏保锁的一个APP。不仅可以作屏保锁&#xff0c;也可以单独保护某些重要程序不被偷窥,例如查看短…

dbms_排名前50位的DBMS面试问答

dbms1) What are the drawbacks of the file system which is overcome on the database management system? 1)在数据库管理系统上克服的文件系统有哪些缺点&#xff1f; Ans: Data redundancy & isolation, difficulty in accessing data, data isolation, and integri…

linux时间

CST代表中国标准时间rtc实时时钟linux主要有两种时间硬件时钟 clock系统时钟 date修改时间 date 03300924必须是两位或者 date -s 2017:03:30将系统时间同步到硬件时间 hwclock -w将硬件时间同步到系统时间 hwclock -s转载于:https://blog.51cto.com/12372297/1911608

查找Python中给定字符串的所有排列

Python itertools Module Python itertools模块 "itertools" are an inbuilt module in Python which is a collection of tools for handling iterators. It is the most useful module of Python. Here, a string is provided by the user and we have to print a…

android 图片叠加xml,Android实现图片叠加效果的两种方法

本文实例讲述了Android实现图片叠加效果的两种方法。&#xff0c;具体如下&#xff1a;效果图&#xff1a;第一种&#xff1a;第二种&#xff1a;第一种是通过canvas画出来的效果:public void first(View v) {// 防止出现Immutable bitmap passed to Canvas constructor错误Bit…

Win10系列:VC++ 定时器

计时器机制俗称"心跳"&#xff0c;表示以特定的频率持续触发特定事件和执行特定程序的机制。在开发Windows应用商店应用的过程中&#xff0c;可以使用定义在Windows::UI::Xaml命名空间中的DispatcherTimer类来创建计时器。DispatcherTimer类包含了如下的成员&#xf…

dbms系统 rdbms_DBMS与传统文件系统之间的区别

dbms系统 rdbmsIntroduction 介绍 DBMS and Traditional file system have some advantages, disadvantages, applications, functions, features, components and uses. So, in this article, we will discuss these differences, advantages, disadvantages and many other …

android 百度地图api密钥,Android百度地图开发获取秘钥之SHA1

最近在做一个关于百度地图的开发。不过在正式开发之前还必须要在百度地图API官网里先申请秘钥&#xff0c;而在申请秘钥的过程中&#xff0c;就需要获取一个所谓的SHA1值。如上所示&#xff0c;但是由于不是正式开发&#xff0c;所以以上的发布版和开发版的SHA1可以先填写相同。…

单位矩阵的逆| 使用Python的线性代数

Prerequisites: 先决条件&#xff1a; Defining a Matrix 定义矩阵 Identity Matrix 身份矩阵 There are matrices whose inverse is the same as the matrices and one of those matrices is the identity matrix. 有些矩阵的逆与矩阵相同&#xff0c;并且这些矩阵之一是单位…

华为荣耀七能升级鸿蒙系统吗,华为鸿蒙系统来了,你知道哪些华为手机荣耀手机可以升级吗?...

从鸿蒙系统第一次开始登场&#xff0c;到现在慢慢有许多鸿蒙系统设备出现&#xff0c;手机市场的格局似乎又要升级变化了。科技树儿了解到&#xff0c;在某数码博主经过和相关人员的沟通核实之后&#xff0c;目前暂定的是搭载华为麒麟710芯片以上的机型&#xff0c;无论华为或荣…

day5-shutil模块

一、简述 我们在日常处理文件时&#xff0c;经常用到os模块&#xff0c;但是有的时候你会发现&#xff0c;像拷贝、删除、打包、压缩等文件操作&#xff0c;在os模块中没有对应的函数去操作&#xff0c;下面我们就来讲讲高级的 文件、文件夹、压缩包 处理模块&#xff1a;shuti…

matlab中now函数_now()方法以及JavaScript中的示例

matlab中now函数JavaScript now()方法 (JavaScript now() method) now() method is a Date class method, it is used to current time in milliseconds, it returns the total number of milliseconds since 01st January 1970, 00:00:00 UTC. now()方法是Date类的一种方法&am…

android 集成x5内核时 本地没有,腾讯浏览服务-接入文档

三、SDK集成步骤1. 第一步下载 SDK jar 包放到工程的libs目录下&#xff0c;将源码和XML里的系统包和类替换为SDK里的包和类&#xff0c;具体对应如下&#xff1a;系统内核SDK内核android.webkit.ConsoleMessagecom.tencent.smtt.export.external.interfaces.ConsoleMessageand…