模拟表达式运算(加减乘除,负数,带括号)
要模拟表达式运算需要目标不同表达式之间的转换关系.
可以参考我的另一篇文章(中后缀表达式转换)
由于水平问题(自己写的总有bug,而且又长又繁琐),所以参考代码选取网上的优秀代码,
但网上的模拟表达式运算要么解释不清楚,要么代码不够完善.
所以我修改了一下网上代码,使其更简单,更完善.
这份代码用数组来表达堆栈.

运算数与运算符用同一个变量p表示栈顶下标.
因为双目运算符是两个元素进行运算,返回一个运算. n个运算数,则有n-1个双目运算符.(只包括双目运算符)
一个运算符对应它右边的运算数.(左括号用0对应,但0不参与运算,具体过程看下面代码)
最后返回1个最终结果.
按步骤分割程序:
(具体解释和细节都添加到注释中)
数据声明(全部采用全局变量):

int number[101];//储存运算数
char symbol[101];//储存运算符
char s[101];//储存字符串
int i=0;//用来遍历字符串
int p=1;//表达栈顶下标,初始化1是为了防止下标越界

入栈操作:

void push()//入栈
{symbol[++p]=s[i];//先增加p值然后将运算符置于栈顶.
}

出栈操作:(每输出一个就进行一次运算,就无需储存输出后的运算符)

void pop()//出栈,并顺带完成相应的运算
{//将number[p](栈顶)与number[p-1]进行运算,并将结果储存在number[p-1]; p--;//出栈后,栈顶下标-1;//number[p]是新的栈顶元素if(symbol[p+1]=='+')//已经弹出的运算符{number[p]+=number[p+1];//运算结果}else if(symbol[p+1]=='-'){number[p]-=number[p+1];}else if(symbol[p+1]=='*'){number[p]*=number[p+1];}else if(symbol[p+1]=='/'){number[p]/=number[p+1];}
}

返回运算符优先级:(可以加上其它优先级的运算符)

int cmp(char a)//返回运算符优先级
{if(a=='*'||a=='/'){return 2;}else if(a=='+'||a=='-'){return 1;}else if(a=='(')//入栈的括号优先级最低{return 0;}return 0;
}

通过优先级比较判断出栈还是入栈:

int can()
{if(cmp(s[i])<=cmp(symbol[p]))//当栈顶运算符优先级大于等于比较运算符时进行出栈 {return 1; }return 0;
}

转换成数字:(可以用辅助字符数组记录数字,然后用atof转换,就可以处理浮点数)

     int sum=0;while(s[i]>='0'&&s[i]<='9')//转化数字 {sum=sum*10+s[i++]-'0';}number[p]=sum;//设为栈顶运算数(因为下一个一定是运算符),初始化为0.

对运算符进行操作:

do{//一定进行一轮 if(s[i]==')')//遇到右括号,不入栈 {while(symbol[p]!='(')//不是左括号则出栈 pop();//栈顶为左括号时 number[--p]=number[p+1];//处理括号对应的0;//此时symbol[p]为'(',因为'('对于的值是没有赋值的0,所以用栈顶的值代替括号对应的值. }else{if(s[i]=='-'&&s[i-1]=='*'||s[i-1]=='/')//处理负数 (单目运算符) {number[p-1]*=-1;//改成负数i++; continue;}while(can())//一直出栈直到可以入栈 pop();push();}i++;
}while(i<strlen(s)&&s[i-1]==')');//判断是否有多重括号

完全代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int number[101];//储存运算数
char symbol[101];//储存运算符
char s[101];//储存字符串
int i=0;//用来遍历字符串
int p=1;//表达栈顶下标,初始化1是为了防止下标越界
void push()//入栈
{symbol[++p]=s[i];//先增加p值然后将运算符置于栈顶.}
void pop()//出栈,并顺带完成相应的运算
{//将number[p](栈顶)与number[p-1]进行运算,并将结果储存在number[p-1]; p--;//出栈后,栈顶下标-1;//number[p]是新的栈顶元素if(symbol[p+1]=='+')//已经弹出的运算符{number[p]+=number[p+1];//运算结果}else if(symbol[p+1]=='-'){number[p]-=number[p+1];}else if(symbol[p+1]=='*'){number[p]*=number[p+1];}else if(symbol[p+1]=='/'){number[p]/=number[p+1];}
}
int cmp(char a)//返回运算符优先级
{if(a=='*'||a=='/'){return 2;}else if(a=='+'||a=='-'){return 1;}else if(a=='('){return 0;}return 0;
}
int can()
{if(cmp(s[i])<=cmp(symbol[p]))//当栈顶运算符优先级大于等于比较运算符时进行出栈 {return 1; }return 0;
}
int main()
{gets(s);s[strlen(s)]=')';symbol[p]='(';//symbol[1]是括号,防止对空栈操作,同时对应第一个数while(i<strlen(s)){while(s[i]=='(')//优先录入左括号 {push();i++;}int sum=0;while(s[i]>='0'&&s[i]<='9')//转化数字 {sum=sum*10+s[i++]-'0';}number[p]=sum;//设为栈顶运算数(因为下一个一定是运算符),初始化为0. do{//一定进行一轮 if(s[i]==')')//遇到右括号,不入栈 {while(symbol[p]!='(')//不是左括号则出栈 pop();//栈顶为左括号时 number[--p]=number[p+1];//处理括号对应的0;//此时symbol[p]为'(',因为'('对于的值是没有赋值的0,所以用栈顶的值代替括号对应的值. }else{if(s[i]=='-'&&s[i-1]=='*'||s[i-1]=='/')//处理负数 (单目运算符) {number[p-1]*=-1;//改成负数i++; continue;}while(can())//一直出栈直到可以入栈 pop();push();}i++;}while(i<strlen(s)&&s[i-1]==')');//判断是否有多重括号}cout<<number[0]<<endl; return 0;
}

注意点:
1.开头就自动在首尾添上括号
2.先p++才入栈,同个p,symbo先被赋值
3.遇到左括号则将对应数值"左移".
4.number[0]是最终结果.
该代码运行流程:
案例:5+9/3

这段代码对于初学者来说可能很复杂,可以多调试几遍或画图来加深理解.
由于水平问题,文章中可能存在不足和错误,欢迎评论指出.

模拟表达式运算(加减乘除,负数,带括号)相关推荐

  1. 表达式求值:从“加减”到“带括号的加减乘除”的实践过程

    本文乃Siliphen原创,转载请注明出处:http://blog.csdn.NET/stevenkylelee ● 为什么想做一个表达式求值的程序 最近有一个需求,策划想设置游戏关卡的某些数值,这个 ...

  2. 【软工Work1】四则加减乘除混合运算(带括号、真分数)

    大家好,很高兴写一片博客给分享自己的这段奇妙的experience of coding! 本来想听老师建议在github上down一些代码的,但之后看网上代码都挺复杂怕难改.而且自己更简单的自己的思路 ...

  3. 基于STM 32、矩阵键盘和独立键盘实现LCD显示的智能计算器(带括号的加减乘除运算、混合四则运算)——普中科技单片机开发试验仪嵌入式开发

    0 引言 智能计算器是嵌入式开发的入门项目,本章使用STM 32芯片作为CPU,并将矩阵键盘和独立键盘作为输入外设,LCD1602作为显示屏,实现可输入的可视化智能计算器. 备注:最终生成的可执行HE ...

  4. 利用栈实现四则运算,带负数,带括号,带小数

    这利用栈实现四则运算,带负数,带括号,带小数,自己写的有问题大家纠正. #include <stdio.h> #include <stdlib.h> #include < ...

  5. matlab实现加减乘除、乘方、开平方、带括号和结果分析的GUI计算器

    matlab实现加减乘除.乘方.开平方.带括号和结果分析的GUI计算器 ,界面如下: 有源码,打赏私聊,微信和电话:15653242819.

  6. 有理数加减乘除 计算机应用带答案,列50道有理数的混合运算(加减乘除)包括答案 初一的...

    列50道有理数的混合运算(加减乘除)包括答案 初一的 列50道有理数的混合运算(加减乘除)包括答案 初一的 人气:123 ℃时间:2019-09-17 20:27:24 优质解答 一定要选我为最佳答案 ...

  7. 【程序】[Qt\C++] 图形化计算器——用QT5实现带括号优先级的GUI编程计算器

    一. 实验任务(实验题目.目的) 搞个图形化的代括号的计算器 二. 任务分析 假设已经有了计算器,实现按下等号的计算算法 学习qt 设置各按钮槽函数 将算法缝合进qt内 设计实现负数.小数 优化代码计 ...

  8. 十以内带括号的加减法(c++)

    这是数据结构老师在课上讲的例题,具体教程可以看我上传的ppt,问题要求如下: 输入一串字符串,为十以内带括号的加减乘除,输出后缀表达式和结果. 解决思路: 先将字符串转化为后缀表达式,然后利用后缀表达 ...

  9. 51-表达式计算(带括号的)

    http://lx.lanqiao.cn/problem.page?gpid=T419  算法训练 表达式计算   时间限制:1.0s   内存限制:256.0MB 问题描述 输入一个只包含加减乖除和 ...

最新文章

  1. nanomsg(ZeroMQ with C)
  2. python numpy创建矩阵、并归一化_每通道以numpy为单位对一批图像进行归一化处理...
  3. 水木告白工作室:Java从零入门之模仿头条资讯(一)
  4. EF选择Mysql数据源
  5. 阿里云的背后故事(希望别被关了)
  6. 三种编码器协议(Endat\BISS\SSI)
  7. Spring中注解实现原理
  8. 纤亿通带你认识和正确使用SFP光模块
  9. PNG图像转ICO的方法
  10. Travel around the UK
  11. android时钟每秒 1,极简时钟
  12. 【Android 屏幕适配】屏幕适配基础概念 ② ( 像素 px 与 密度无关像素 dip | 像素 px 与 密度无关像素 dip 在不同屏幕像素密度 dpi 下的换算关系 )
  13. uniapp对接微信公众号H5微信支付、分享、小程序隐藏右上角分享胶囊
  14. html left属性,CSS属性参考 | left
  15. 华为数字化转型之道 方法篇 第三章 数字化转型框架
  16. vite 配置修改 antd 主题色
  17. 算法题-报数游戏(java)
  18. linux 查服务器序列号,Linux 查询服务器序列号命令
  19. Oracle 闪回技术详解
  20. 用Python分析了近几年富豪排行榜,我酸了...

热门文章

  1. 陪孩子一起学python创客童年_Python课程
  2. 健康——基本运动的卡路里计算公式
  3. Linux vim编辑文件查找指定的字符串
  4. 创业者能从猎豹移动身上取到哪些经?
  5. CAD文件版本怎么转换?怎么将高版本文件转换成低版本
  6. 我国改革开放和现代化建设中一些实际问题的思考
  7. 面向服务的大数据分析平台解决方案
  8. 气相色谱仪的基本原理与结构
  9. 让AI变得唾手可得才是云计算的最新战场
  10. 优维科技王津银:SaaS模式是中小企业实现数字化转型的“利器”