【栈】1106. 解析布尔表达式

本文涉及知识点

LeetCode 1106. 解析布尔表达式

布尔表达式 是计算结果不是 true 就是 false 的表达式。有效的表达式需遵循以下约定:

't',运算结果为 true

'f',运算结果为 false

'!(subExpr)',运算过程为对内部表达式 subExpr 进行 逻辑非(NOT)运算

'&(subExpr1, subExpr2, ..., subExprn)',运算过程为对 2 个或以上内部表达式 subExpr1, subExpr2, ..., subExprn 进行 逻辑与(AND)运算

'|(subExpr1, subExpr2, ..., subExprn)',运算过程为对 2 个或以上内部表达式 subExpr1, subExpr2, ..., subExprn 进行 逻辑或(OR)运算

给你一个以字符串形式表述的 布尔表达式 expression,返回该式的运算结果。

题目测试用例所给出的表达式均为有效的布尔表达式,遵循上述约定。

示例 1:

输入:expression = "&(|(f))"

输出:false

解释:

首先,计算 |(f) --> f ,表达式变为 "&(f)" 。

接着,计算 &(f) --> f ,表达式变为 "f" 。

最后,返回 false 。

示例 2:

输入:expression = "|(f,f,f,t)"

输出:true

解释:计算 (false OR false OR false OR true) ,结果为 true 。

示例 3:

输入:expression = "!(&(f,t))"

输出:true

解释:

首先,计算 &(f,t) --> (false AND true) --> false --> f ,表达式变为 "!(f)" 。

接着,计算 !(f) --> NOT false --> true ,返回 true 。

提示:

1 <= expression.length <= 2 * 104

expression[i] 为 '('、')'、'&'、'|'、'!'、't'、'f' 和 ',' 之一

递归

这个容易想到。

不需要数据栈,只需要操作符栈。本题运算符和操作数都是单字符,很好解析。

除逗号和右括号外,全部入栈。

忽略逗号。

遇到右括号,出栈直到左括号出栈。

记录出栈的 t f数量。记录并出栈运算符。

运算结果入栈。

代码

cpp 复制代码
class Solution {
public:
	bool parseBoolExpr(string exp) {
		for (const auto& ch : exp) {
			if (',' == ch) { continue; }
			if (')' == ch) {
				int cnts[2] = { 0 };
				while ('(' != m_sta.top()) {
					cnts['t' == m_sta.top()]++;
					m_sta.pop();
				}
				m_sta.pop();
				bool bRet = true;
				if ('&' == m_sta.top()) {
					bRet = (0 == cnts[0]);
				}else if ('|' == m_sta.top()) {
					bRet = (0 != cnts[1]);
				}
				else {
					bRet = cnts[0];
				}
				m_sta.pop();
				m_sta.push(bRet ? 't' : 'f');
				continue;
			}
			m_sta.emplace(ch);
		}
		return 't' == m_sta.top();
	}
	stack<char> m_sta;
};

单元测试

cpp 复制代码
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 expression;
	TEST_CLASS(UnitTest)
	{
	public:
		TEST_METHOD(TestMethod0)
		{
			expression = "&(|(f))";
			auto res = Solution().parseBoolExpr(expression);
			AssertEx(false,res);
		}
		TEST_METHOD(TestMethod1)
		{
			expression = "|(f,f,f,t)";
			auto res = Solution().parseBoolExpr(expression);
			AssertEx(true, res);
		}
		TEST_METHOD(TestMethod2)
		{
			expression = "!(&(f,t))";
			auto res = Solution().parseBoolExpr(expression);
			AssertEx(true, 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++**实现。

相关推荐
捕鲸叉15 分钟前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer20 分钟前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq22 分钟前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
wheeldown1 小时前
【数据结构】选择排序
数据结构·算法·排序算法
青花瓷2 小时前
C++__XCode工程中Debug版本库向Release版本库的切换
c++·xcode
观音山保我别报错2 小时前
C语言扫雷小游戏
c语言·开发语言·算法
幺零九零零3 小时前
【C++】socket套接字编程
linux·服务器·网络·c++
TangKenny3 小时前
计算网络信号
java·算法·华为
景鹤3 小时前
【算法】递归+深搜:814.二叉树剪枝
算法
iiFrankie3 小时前
SCNU习题 总结与复习
算法