模拟表达式运算(加减乘除,负数,带括号)
模拟表达式运算(加减乘除,负数,带括号)
要模拟表达式运算需要目标不同表达式之间的转换关系.
可以参考我的另一篇文章(中后缀表达式转换)
由于水平问题(自己写的总有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
这段代码对于初学者来说可能很复杂,可以多调试几遍或画图来加深理解.
由于水平问题,文章中可能存在不足和错误,欢迎评论指出.
模拟表达式运算(加减乘除,负数,带括号)相关推荐
- 表达式求值:从“加减”到“带括号的加减乘除”的实践过程
本文乃Siliphen原创,转载请注明出处:http://blog.csdn.NET/stevenkylelee ● 为什么想做一个表达式求值的程序 最近有一个需求,策划想设置游戏关卡的某些数值,这个 ...
- 【软工Work1】四则加减乘除混合运算(带括号、真分数)
大家好,很高兴写一片博客给分享自己的这段奇妙的experience of coding! 本来想听老师建议在github上down一些代码的,但之后看网上代码都挺复杂怕难改.而且自己更简单的自己的思路 ...
- 基于STM 32、矩阵键盘和独立键盘实现LCD显示的智能计算器(带括号的加减乘除运算、混合四则运算)——普中科技单片机开发试验仪嵌入式开发
0 引言 智能计算器是嵌入式开发的入门项目,本章使用STM 32芯片作为CPU,并将矩阵键盘和独立键盘作为输入外设,LCD1602作为显示屏,实现可输入的可视化智能计算器. 备注:最终生成的可执行HE ...
- 利用栈实现四则运算,带负数,带括号,带小数
这利用栈实现四则运算,带负数,带括号,带小数,自己写的有问题大家纠正. #include <stdio.h> #include <stdlib.h> #include < ...
- matlab实现加减乘除、乘方、开平方、带括号和结果分析的GUI计算器
matlab实现加减乘除.乘方.开平方.带括号和结果分析的GUI计算器 ,界面如下: 有源码,打赏私聊,微信和电话:15653242819.
- 有理数加减乘除 计算机应用带答案,列50道有理数的混合运算(加减乘除)包括答案 初一的...
列50道有理数的混合运算(加减乘除)包括答案 初一的 列50道有理数的混合运算(加减乘除)包括答案 初一的 人气:123 ℃时间:2019-09-17 20:27:24 优质解答 一定要选我为最佳答案 ...
- 【程序】[Qt\C++] 图形化计算器——用QT5实现带括号优先级的GUI编程计算器
一. 实验任务(实验题目.目的) 搞个图形化的代括号的计算器 二. 任务分析 假设已经有了计算器,实现按下等号的计算算法 学习qt 设置各按钮槽函数 将算法缝合进qt内 设计实现负数.小数 优化代码计 ...
- 十以内带括号的加减法(c++)
这是数据结构老师在课上讲的例题,具体教程可以看我上传的ppt,问题要求如下: 输入一串字符串,为十以内带括号的加减乘除,输出后缀表达式和结果. 解决思路: 先将字符串转化为后缀表达式,然后利用后缀表达 ...
- 51-表达式计算(带括号的)
http://lx.lanqiao.cn/problem.page?gpid=T419 算法训练 表达式计算 时间限制:1.0s 内存限制:256.0MB 问题描述 输入一个只包含加减乖除和 ...
最新文章
- nanomsg(ZeroMQ with C)
- python numpy创建矩阵、并归一化_每通道以numpy为单位对一批图像进行归一化处理...
- 水木告白工作室:Java从零入门之模仿头条资讯(一)
- EF选择Mysql数据源
- 阿里云的背后故事(希望别被关了)
- 三种编码器协议(Endat\BISS\SSI)
- Spring中注解实现原理
- 纤亿通带你认识和正确使用SFP光模块
- PNG图像转ICO的方法
- Travel around the UK
- android时钟每秒 1,极简时钟
- 【Android 屏幕适配】屏幕适配基础概念 ② ( 像素 px 与 密度无关像素 dip | 像素 px 与 密度无关像素 dip 在不同屏幕像素密度 dpi 下的换算关系 )
- uniapp对接微信公众号H5微信支付、分享、小程序隐藏右上角分享胶囊
- html left属性,CSS属性参考 | left
- 华为数字化转型之道 方法篇 第三章 数字化转型框架
- vite 配置修改 antd 主题色
- 算法题-报数游戏(java)
- linux 查服务器序列号,Linux 查询服务器序列号命令
- Oracle 闪回技术详解
- 用Python分析了近几年富豪排行榜,我酸了...