题目描述

输入一个表达式(用字符串表示),求这个表达式的值。

保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。

输入:+3+2*{1+2*[-4/(8-6)+7]}

输出:25

思路

  1. 使用两个栈来维护计算过程:一个数字栈,用来存储操作数字;一个操作符栈,用来存储‘+’,‘-’, ‘*’,‘/’ ,‘(’,‘)’,‘[’, ‘]’,‘{’ ,‘}’等操作符
  2. 如果当前运算符优先级('*/')高于栈顶运算符('+-')优先级,则将运算符入栈;反之,从数字栈中弹出两个数,从运算符栈中弹出栈顶运算符,进行运算,数字栈压入运算结果,符号栈压入当前运算符。重复该操作直到不满足条件。
  3. 出现左括号‘(’,则直接压入;出现右括号‘)’,则从数字栈中弹出两个数,从运算符栈中弹出栈顶运算符,进行运算,数字栈压入运算结果,重复该操作直到栈顶元素为左括号‘(’。

难点:

  1. 将数字从字符串中提取出来,而且要考虑正负号
  2. 运算符有优先级:有括号先算括号里的,再算乘除,最后加减,要满足从左往右运算顺序

注意:由于有除法运算,应该使用double格式来保存计算结果

使用到的字符串操作函数

find()与find_first_of()

string (1)

size_t find (const string& str, size_t pos = 0) const noexcept;

c-string (2)

size_t find (const char* s, size_t pos = 0) const;

buffer (3)

size_t find (const char* s, size_t pos, size_type n) const;

character (4)

size_t find (char c, size_t pos = 0) const noexcept;

 string s = "hello world!";cout << s.find('o') << endl;//4cout << s.find('o', 5) << endl;//7cout << s.find("world") << endl;//6cout << s.find("word") << endl;//4294967295,未找到cout << s.find_first_of("word") << endl;//4,“wor” 出现在原字符串中,cout << s.find_last_of('o') << endl;//7

在当前字符串s中搜索传入参数字符串或者字符在s中首次出现的下标,与find_first_of()不同的是,find_first_of()找到了首个匹配的实例之后就不找了,就认定找寻成功,返回首个字符的下标,而find()则是要求完全匹配。如果输入了pos参数,则从下标pos开始查找。

查找失败:返回string::npos

static const size_t npos = -1;
//npos is a static member constant value with the greatest possible value for an element of type size_t.

npos是一个静态成员常量,其值为size_t类型的最大值:4294967295,用来表示没找到元素。

substr()

截取字符串

string substr (size_t pos = 0, size_t len = npos) const;

第一个参数pos是开始截取的位置下标,第二个参数len是截取的长度 ,若len==npos,意思是截取字符串从pos直到末尾

stoi()与stod()

将字符串转成int类型或double类型

实现代码

#include<iostream>
#include<stack>
#include<string>
using namespace std;
string nums = "0123456789";
//比较函数,用于比较当前操作符和栈顶操作符的优先级
//如果当前操作符优先级大于栈顶优先级,返回false
//如果栈顶操作符为左括号(
//如果当前操作符优先级小于栈顶优先级,true
//还要满足从左往右计算顺序,如果当前操作符与栈顶操作符为同级关系,返回true
//返回true说明此时需要将栈顶操作符弹出,用于计算
bool cmp(char top, char now){if(top == '('){return false;}else if((top == '-' || top == '+') && (now == '*' || now == '/')){return false;}return true;
}
//计算,从数字栈中弹出两个数字,操作符栈中弹出操作符
void calculate(stack<double> &num,stack<char> &op){
//     数字栈中数字的顺序也有要求
//     第一个弹出的数字在后面,第二个弹出的在前面double b = num.top();num.pop();double a = num.top();num.pop();char c = op.top();op.pop();if(c == '+') a = a+b;else if(c == '-') a = a-b;else if(c == '*') a = a*b;else if(c == '/') a = a/b;//将结果放入数字栈num.push(a);return ;
}
int main(void){string s;while(getline(cin, s)){//数字栈stack<double> num_stk;//操作符栈stack<char> op_stk;//预处理,将算式用括号括起来op_stk.push('(');s += ')';//算式的第一个应该是数字bool isNextOp = false;for(int i=0; i<s.size(); ++i){//左括号的话,直接压入操作符栈,将大中小括号都当做小括号处理if(s[i] == '(' || s[i] == '[' || s[i] == '{'){op_stk.push('(');}//右括号的话就可以开始计算,直到遇到与之对应的左括号else if(s[i] == ')' || s[i] == ']' || s[i] == '}'){while(op_stk.top() != '(') //计算calculate(num_stk,op_stk);//弹出此时的(op_stk.pop();}//除括号外,数字和操作符应该是间隔排列的,而且算式的第一个应该是数字//若没有括号,需要考虑操作符优先级问题,并且是从左往右计算else if(isNextOp){while(cmp(op_stk.top(),s[i])){//计算calculate(num_stk,op_stk);}op_stk.push(s[i]);isNextOp = false;}//将数字从字符串中提取出来else{int j = i;//+ -符号可能是正负符号if(s[j] == '+' || s[j] == '-') ++i;//数字可能有多位,在0-9中while(nums.find(s[i]) != nums.npos) ++i;//i和j之间的字符即为数字//将数字提取,并压入数字栈//num_stk.push(stod(nums.substr(j,i-j)));num_stk.push((double)stoi(s.substr(j,i-j)));--i;//当前为数字,所以下一个为操作符isNextOp = true;}}//数字栈顶的元素即为最后结果cout<<num_stk.top()<<endl;}return 0;
}

算法动图

算法动图制作方法

在网上经常看见别人写的算法图解动图,本以为有专门的软件可以用,但是没有找了一圈并没有发现这种软件。

网上的一些动图开源项目:

掘金

https://github.com/MisterBooo/Play-With-Sort-OC

于是自己决定采用土办法,使用PPT+录屏软件来制作算法动图:

发现一个很好用的gif录屏工具:screentogif

下载链接:ScreenToGif

首先在PPT中将算法步骤一张一张描绘出来,然后使用gif录屏软件制即可:

当前算法PPT下载地址:

图解PPT

C++四则运算字符串解析(附动图以及动图制作方法)相关推荐

  1. 任性动图---制作动图、录屏软件 可方便添加各种文字

    GIF动图制作.屏幕区域录屏.全屏录屏.录视频         特色:强大的添加文字功能,可直接在屏幕上添加各种文字 傻瓜式创作动图.创作动图就是这么简单.就是这么任性!!! 文字编辑.照片PS.动图 ...

  2. html gif循环播放,Easy GIF Animator 7设置gif动图循环播放次数的方法

    gif动态图在我们的生活中是十分常见的,很多小伙伴们在使用聊天工具的时候都会使用一些 动态的表情包,这些表情包文件给我们的了解增加了很多的乐趣.不知道大家在使用这些表情包的时候是否有发现这样的一种情况 ...

  3. 动图设置动图设置动图设置

    动图上传审核失败怎么处理

  4. OLED上播放动图的一种笨方法

    声明:本文章纯属学习研究,之所以使用这个素材,一是觉着好玩,二是在这个动图中,人物的动作比较大,这样子效果比较好.没有冒犯他人之意. 再者,文章若有侵权请联系本人进行删除. 工具:硬件:STC8A8K ...

  5. 真是一篇神奇的文章 动图DIY - 动图剪辑 - 录屏 - 画画动图 (无需VIP的软件推荐)

    很多人想自己去搞一些 动图 ,去了好多网址或者app,不是收费

  6. # 导入一张视频 导入一张gif动图 将动图添加到视频中 保存为新的视频

    import cv2 import numpy as np# 读取视频 cap = cv2.VideoCapture('D:/video/j.mp4') # 读取gif动图 gif = cv2.imr ...

  7. excel甘特图模板_最简单的Excel甘特图制作方法,只用一条公式,项目进度一目了然...

    在工作中,每个部门或者每个人可能都会制定半年或一年的工作计划表,这样能更清楚的知道每个时间段自己要完成的工作和未完成的工作,然而,大多数人的计划表也只是简单的列举几点,微信就直接发给主管了,这样的计划 ...

  8. 文字gif闪图怎么做?高效的gif闪图制作方法

    相信不少新媒体行业的小伙伴,一定都见过那种闪动文字效果的gif动图吧.效果非常的炫酷还很吸引人们的眼球,但是作为设计小白这种闪烁gif图要怎么制作呢?有没有那种小白也能轻松上手的工具呢? 一.什么样的 ...

  9. HTML中jquery轮播图旋转,jquery 3d轮播图制作方法 (实现旋转轮播图)

    /*轮播*/ .lb_gl{margin-bottom: 30px;background: url(../images/bg_3d.png);background-size: 100% 100%;he ...

最新文章

  1. AD备份文件安装额外域控制器
  2. 云计算--Presto
  3. 1289 大鱼吃小鱼
  4. css img 适配尺寸_CSS容易使人蒙圈的几个经典问题
  5. java合并list_java合并list方法代码实例
  6. 打开c语言运行不了_C语言——菜鸟和大神的分水岭:内存、线程、进程
  7. validatebox自定义验证规则以及使用
  8. (转)使用JMeter进行Web压力测试
  9. 微积分知识点回顾与总结(二)极限
  10. mysql联合索引原理
  11. Math.random随机数生成公式
  12. 2021年中国粮食行业发展现状分析,粮食播种面积、产量再度迎来上涨「图」
  13. how-to-solve-the-specific-problem,learn-this,imitate-this
  14. Swift游戏实战-跑酷熊猫 04 熊猫的跳和滚的动作
  15. python 金融发欺诈_python金融反欺诈-项目实战
  16. 医学图像配准中的深度学习综述论文解读
  17. 008 怎么取消隐藏文件扩展名
  18. 软路由openwrt新手教程
  19. 从智能监理到个人随身智能应用,尽情体验tooz智能眼镜
  20. CISCO X8系列AP升级详解

热门文章

  1. Element el-icon 图标组件详解
  2. 三次B样条曲线拟合算法
  3. AlexNet_tensorflow2.1_实现狼狗分类
  4. .NET内存性能分析宝典
  5. 利用条件运算符的嵌套实现:学习成绩=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示
  6. 包收录外链平台都有哪些
  7. 用爬虫批量采集阿里巴巴1688商品数据
  8. 阿里云centos7.2部署tomcat10
  9. 布林带止盈止损策略改进
  10. 国密、DES、RSA加密算法金属密码键盘ZT598的应用