题目

实现一个基本的计算器来计算一个简单的字符串表达式的值。
字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格 。

示例 1:
输入: "1 + 1"
输出: 2
示例 2:
输入: " 2-1 + 2 "
输出: 3
示例 3:
输入: "(1+(4+5+2)-3)+(6+8)"
输出: 23

说明:
你可以假设所给定的表达式都是有效的。
请不要使用内置的库函数 eval。

来源:力扣(LeetCode)
链接:Leetcode224基本计算器

思路:

采用双栈,一个是数值栈number_stack;另一个操作符栈operation_stack来进行计算。

整个过程引入三个状态进行转换:state_begin,number_state,operation_state,转换关系如下图。

图片:来源小象学院B站视频

  1. state_begin是默认状态,数字则跳转到number_state,左括号则跳转到operation_state
  2. number_state处理的是数字,则进行字符串转换为数字;此外,压栈并且计算,控制跳转到operation_state
  3. operation_state处于该状态的i,需要分情况处理,如上图。

代码


#include<iostream>
#include<string>
#include<stack>
using namespace std;class Solution {public:
//计算加和减法void compute(stack<int> &number_stack,stack<char> &operation_stack){int num2,num1;if(number_stack.size()<2)return;//只有一个数的情况num2=number_stack.top();number_stack.pop();num1=number_stack.top();number_stack.pop();if(operation_stack.top()=='+')number_stack.push(num1+num2);else if(operation_stack.top()=='-')number_stack.push(num1-num2);operation_stack.pop();//该运算符出栈}//int calculate(string s) {static const int state_begin=0;//三个状态变量static const int number_state=1;static const int operation_state=2;std::stack<int> number_stack;std::stack<char> operation_stack;int number =0;//进行压栈操作使用int state=state_begin;//初始状态int compute_flag=0;//可以进行运算的标记,=1表示可进行运算for(int i=0;i<s.length();i++){if(s[i]==' ')continue;//有空格时候的处理switch(state)//三个状态的控制{case state_begin://初始状态if(s[i]>='0'&&s[i]<='9')state=number_state;else    state=operation_state;i--;break;case number_state://处理字符串转化为数字if(s[i]>='0'&&s[i]<='9'){number=number*10+s[i]-'0';//转化为数字}else//这个状态下会遇到+-{number_stack.push(number);//把“+”“-”前面的数字入栈if(compute_flag==1)//查看是否可以计算compute(number_stack,operation_stack);number=0;//因为已经完成入栈操作,此时number设为零          i--;//指针退格,因为此时i指的是加号或者减号state=operation_state;//状态转换}break;case operation_state://操作符状态if(s[i]=='+'||s[i]=='-')//遇到的是加号或减号{//加减法符号入栈operation_stack.push(s[i]);compute_flag=1;//可计算标志赋值1}else if(s[i]=='('){//左括号后面跟着的是数字state=number_state;compute_flag=0;}else if(s[i]>='0'&& s[i]<='9'){//是数字,需要转换到number_state处理,所以i--重新进入switchstate=number_state;i--;}else if(s[i]==')'){//右括号可以计算compute(number_stack,operation_stack);}break;}}if(number!=0)//只有一个元素的情况和其他情况{number_stack.push(number);compute(number_stack,operation_stack);}if(number==0&&number_stack.empty())return 0;return number_stack.top();  //返回栈顶元素}};int main()
{string s="1+121-(14+(5-6))";Solution solve;cout<<solve.calculate(s)<<endl;}

测试结果


这是表达式s="1+121-(14+(5-6))"的值。

总结

本题在leetcode中标记为hard难度,这里采用的是有限状态转换法。

每个状态作何处理,这个需要想清楚。
同时需要注意的是指针的退格,这里的 循环遍历 i 起到指针的作用。
比如,第i个字符进入操作符状态(operation_state),如果它是数,不是±符号,我们需要将其状态转变(number_state),然后让该位置i重新进入到switch中,这里就需要指针的退格(i- -) 。

进行栈内运算时,需要设置标记位,遇到右括号可以进行计算。

参考资料

B站leetcode刷题视频av29912609

Leetcode224 基本加减计算器-双栈和状态转换相关推荐

  1. 易语言练习笔记-大叔篇(3)-加减计算器

    易语言练习笔记-大叔篇(3)-加减计算器 省约时间,直接上代码,界面设计如下: 看代码输入效果,运行效果如下: 看懂的掌声.回复.关注,感谢! 以下没时间不需要看.... 到数值( ) 调用格式: 〈 ...

  2. 时间加减计算器_FRM计算器使用流程你知道吗?

    金融计算器对于FRM考试有多重要,从进考场必备用品就可以看出来. 准考证,计算器是必须带的,忘了准考证,你就只能明年再战,忘了计算器,哪怕你是学神,想要通过考试大概率也是要烧香的. FRM考试与其他类 ...

  3. MFC实现简单连续加减计算器

    C++初学者完成课程作业,时间有限没实现括号运算,也可以使用vector容器写,我这里没有用,思路是一样的. 添加类成员: void MyCalculate(); //计算函数CString m_st ...

  4. python10以内的加减计算器_python学习之实现简单计算器(加减乘除)小学生能力测试-Go语言中文社区...

    1.小学生算术能力测试系统: 题目要求: 设计一个程序,用来实现帮助小学生进行百以内的算术练习,它具有以下功能: 提供10道加.减.乘或除四种基本算术运算的题目: 练习者根据显示的题目输入自己的答案, ...

  5. 时间加减计算器_手机上的计算器这样也可以,太方便了,赶快转告家人朋友

    随着科技的发展,大家无论是写字还是算术,都很少手写,大多数都是用手机或者电脑来操作完成.慢慢的,我们大脑对算术越来越不敏感,一提到算术,相信大家第一时间想到的就是使用计算器.我们每个人的手机上都自带一 ...

  6. python实现一个简单的加法计算器_Python简易项目 加减计算器的实现

    Python Calculator 1.0 支持功能:add.minus 输入表达式不含括号,允许不加'=' 非常简单的一个小计算器,还缺少很多功能,目的是为了练练手. 日后会对其进行更新. 源码 # ...

  7. 时间加减计算器_小学生苦练加减乘除计算“基本功”,有没有必要?

    作者 | 民间数学家 来源 | 职业数学家在民间 一 在多个家长群做了调查之后,我发现目前小学数学教育阶段有个很普遍的现象,许多学校的数学老师都会要求小学生(在数学课本的课后习题之外)每天在家额外再练 ...

  8. 单片机加减法计算器_大神们!汇编,数码管显示简易加减计算器

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 YJ EQU 50H ;结果存放 YJ1 EQU 51H ;中间结果存放 GONG EQU 52H ;功能键存放 ORG 0000H LJMP START ...

  9. 时间加减计算器_手机计算器别只拿来算数!教你这样开启,能唤出隐藏功能,很实用...

    说到手机上的计算器,如今已经很少有人使用.人们对计算器的用途大多都是算数,但是你们真的认为手机计算器真的只有算数那么简单吗?如果你真的这样认为,那真的大错特错了.其实计算器上还有许多非常实用的小技巧, ...

最新文章

  1. 函数要多小才够好——谈小函数之道
  2. 公司使用360安全产品造成的CRM系统故障!
  3. 每天一道LeetCode-----以单词为单位逆序字符串,每个单词之间以一个空格分隔(原字符串中可能有多个空格)
  4. 完成AOP 顶层设计-AopProxy
  5. 3 MapReduce计算模型
  6. winows系统打开telnet功能
  7. Android SubsamplingScaleImageView(subsampling-scale-image-view)单双击长按事件【系列2】
  8. venue11 Android,戴尔新平板四连发 抛弃WinRT回归Android
  9. restTemplate设置访问超时
  10. 如何设置固定宽度 td ?
  11. 1、fiddler 下载、安装、配置
  12. 使用V-ASSISTANT软件配置V90伺服驱动器参数的具体步骤详解
  13. BSC-币安智能链主网节点搭建(详细步骤)
  14. php ucenter home登录,UCenter Home 2.0 正式版现正式下载!!
  15. android图片处理,让图片变成圆形
  16. ubuntu写yacc
  17. 配置JDK / JAVA
  18. c语言温度换算作业,[编程入门]温度转换 (C语言代码)
  19. 性能测试报告(入门)
  20. 异星工厂怎么制造机器人_异星工厂建设机器人怎么用 异星工厂建设机器人机制介绍-街机中国...

热门文章

  1. linux tar命令 打包 解压
  2. python 类方法调用一次自增1_Python+selenium自动化脚本如何使数字每次执行自增1
  3. 用神经网络构造一个基于分类的多体系统
  4. 8.5 特征选择-机器学习笔记-斯坦福吴恩达教授
  5. 【PC工具】更新github下载加速器,github项目辅助下载工具,github高速下载
  6. 如何开发一个能拯救银河系的充电器
  7. 【Flocking、PPO无人机群控制算法】基于Flocking和PPO深度强化学习的无人机群控制算法的MATLAB仿真
  8. Webpack介绍和使用(配置环境变量,打包依赖)
  9. java 自适应响应式 网站 源码 SSM 生成 静态化 手机 平板 PC
  10. 如何利用Python网络爬虫爬取微信朋友圈动态--附代码(下)