• 【栈】224. 基本计算器


    本文涉及知识点

    LeetCode 224. 基本计算器

    给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
    注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() 。

    示例 1:

    输入:s = “1 + 1”
    输出:2
    示例 2:

    输入:s = " 2-1 + 2 "
    输出:3
    示例 3:

    输入:s = “(1+(4+5+2)-3)+(6+8)”
    输出:23

    提示:

    1 <= s.length <= 3 * 105
    s 由数字、‘+’、‘-’、‘(’、‘)’、和 ’ ’ 组成
    s 表示一个有效的表达式
    ‘+’ 不能用作一元运算(例如, “+1” 和 “+(2 + 3)” 无效)
    ‘-’ 可以用作一元运算(即 “-1” 和 “-(2 + 3)” 是有效的)
    输入中不存在两个连续的操作符
    每个数字和运行的计算将适合于一个有符号的 32位 整数

    由于只有 加、减、负号,所有不需要操作数栈,只需要操作符栈,±(三种。数值直接运算。

    操作数

    当前栈,负号的总数为偶数,则将当前数值加到结果,否则从结果中减去当前值。
    如果当前栈顶为±,出栈。

    左括号、+、-

    入栈

    右括号

    出栈括号,及前面的±号。

    注意:cnt 记录栈中负号的数量。

    代码

    核心代码

    class Solution {
    public:
    	int calculate(string s) {
    		int iRet = 0;
    		for (int i = 0; i < s.length(); i++) {
    			if (' ' == s[i]) { continue; }
    			if (('(' == s[i]) || ('+' == s[i])) {
    				m_sta.emplace(s[i]);
    			}
    			else if('-' == s[i]) {
    				m_sta.emplace(s[i]);
    				m_iCnt++;
    			}
    			else if (')' == s[i]) {
    				m_sta.pop();
    				PopSign();
    			}
    			else {
    				int num = 0;
    				while (isdigit(s[i])) {
    					num = 10 * num + (s[i] - '0');
    					i++;
    				}
    				if (1 & m_iCnt) {
    					iRet -= num;
    				}
    				else {
    					iRet += num;
    				}
    				PopSign();
    				i--;
    			}
    		}
    		return iRet;
    	}
    	void PopSign() {
    		if (m_sta.empty() || ('(' == m_sta.top())) { return; }
    		if ('-' == m_sta.top()) { m_iCnt--; };
    		m_sta.pop();
    	}
    	stack<char> m_sta;
    	int m_iCnt = 0;
    };
    

    单元测试

    template<class T1,class T2>
    void AssertEx(const T1& t1, const T2& t2)
    {
    	Assert::AreEqual(t1 , t2);
    }
    
    template<class T>
    void AssertEx(const vector<T>& v1, const vector<T>& v2)
    {
    	Assert::AreEqual(v1.size(), v2.size());	
    	for (int i = 0; i < v1.size(); i++)
    	{
    		Assert::AreEqual(v1[i], v2[i]);
    	}
    }
    
    template<class T>
    void AssertV2(vector<vector<T>> vv1, vector<vector<T>> vv2)
    {
    	sort(vv1.begin(), vv1.end());
    	sort(vv2.begin(), vv2.end());
    	Assert::AreEqual(vv1.size(), vv2.size());
    	for (int i = 0; i < vv1.size(); i++)
    	{
    		AssertEx(vv1[i], vv2[i]);
    	}
    }
    
    namespace UnitTest
    {
    	string s;
    	TEST_CLASS(UnitTest)
    	{
    	public:
    		TEST_METHOD(TestMethod0)
    		{	
    			s = "1 + 1";
    			auto res = Solution().calculate(s);
    			AssertEx(2,res);
    		}
    		TEST_METHOD(TestMethod1)
    		{
    			s =" 2-1 + 2 ";
    			auto res = Solution().calculate(s);
    			AssertEx(3, res);
    		}
    		TEST_METHOD(TestMethod2)
    		{
    			s = "(1+(4+5+2)-3)+(6+8)";
    			auto res = Solution().calculate(s);
    			AssertEx(23, res);
    		}
    		TEST_METHOD(TestMethod3)
    		{
    			s = "2147483647";
    			auto res = Solution().calculate(s);
    			AssertEx(2147483647, res);
    		}
    
    		
    	};
    }
    

    扩展阅读

    视频课程

    有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
    https://edu.csdn.net/course/detail/38771

    如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
    https://edu.csdn.net/lecturer/6176

    相关下载

    想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
    https://download.csdn.net/download/he_zhidan/88348653

    我想对大家说的话
    《喜缺全书算法册》以原理、正确性证明、总结为主。
    闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
    子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
    如果程序是一条龙,那算法就是他的是睛

    测试环境

    操作系统:win7 开发环境: VS2019 C++17
    或者 操作系统:win10 开发环境: VS2022 C++17
    如无特殊说明,本算法用**C++**实现。

  • 相关阅读:
    使用navicat for mongodb连接mongodb
    解决ROS的cv_bridge与自己安装的opencv的版本冲突的问题
    内修昇思MindSpore AI框架,外重行业汇聚,华为大模型的不平凡之路
    力扣2296.设计一个文本编辑器
    2023年SpinalHDL应用前景探索线上研讨会----征集演讲嘉宾
    AUTOSAR汽车电子嵌入式编程精讲300篇-基于AUTOSAR架构的AT控制系统研究与实现
    redis部署与管理
    第57篇 QML 之 JS 数据类型详解(必看)
    荧光染料AF430 tetrazine,AF430 四嗪,深橙色固体
    Leedcode【899】. 有序队列——Java解法
  • 原文地址:https://blog.csdn.net/he_zhidan/article/details/139154150