1106. 解析布尔表达式

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

有效的表达式需遵循以下约定:

"t",运算结果为 True
"f",运算结果为 False
"!(expr)",运算过程为对内部表达式 expr 进行逻辑 非的运算(NOT)
"&(expr1,expr2,...)",运算过程为对 2 个或以上内部表达式 expr1, expr2, ... 进行逻辑 与的运算(AND)
"|(expr1,expr2,...)",运算过程为对 2 个或以上内部表达式 expr1, expr2, ... 进行逻辑 或的运算(OR)
 

示例 1:

输入:expression = "!(f)"
输出:true
示例 2:

输入:expression = "|(f,t)"
输出:true
示例 3:

输入:expression = "&(t,f)"
输出:false
示例 4:

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

提示:

1 <= expression.length <= 20000
expression[i] 由 {'(', ')', '&', '|', '!', 't', 'f', ','} 中的字符组成。
expression 是以上述形式给出的有效表达式,表示一个布尔值。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/parsing-a-boolean-expression
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:
根据题意我们可以知道,一个运算符一定会跟随一对括号,比如 (t)(t)。
所以我们可以直接判断 expression[0],得到最外层的运算符,根据运算符处理内层的表达式。

如果不是运算符,肯定就是 t 或者 f 直接判断即可
如果是 !!,里面要么就是单一的字符,要么就是一个新的表达式。再调用 parseBoolExpr 解析并取反即可。
如果是 & 或者 |∣, 需要对里面每个表达式分别求解。通过括号匹配,拿到第一个 ( 匹配的 ) 里面的表达式,再通过 parseBoolExpr 计算出值。
在计算 & 的时候,如果有一个值为 false,可以提前结束计算。同理,在计算 |∣ 时, 如果有一个值为 true,也可以提前结束计算。

作者:resara
链接:https://leetcode.cn/problems/parsing-a-boolean-expression/solution/golang-fen-jie-by-resara/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

func parseBoolExpr(expression string) bool {
	start, end := 2, len(expression)-1
	switch expression[0] {
	case '!':
		return Not(expression[start:end])
	case '&':
		return AndOr(expression[start:end], true)
	case '|':
		return AndOr(expression[start:end], false)
	default:
		return expression == "t"
	}
}

// flag &: true |: false
func AndOr(exp string, flag bool) bool {
	pre, idx := 0, 0
	for i := 0; i < len(exp); i++ {
		if exp[i] == '(' {
			if pre == 0 {
				idx = i
			}
			pre++
		} else if exp[i] == ')' {
			pre--
			if pre == 0 {
				t := parseBoolExpr(exp[idx-1 : i+1])
				if !t && flag {
					return false
				}
				if t && !flag {
					return true
				}
			}
		} else {
            if pre <= 0 {
				if exp[i] == 'f' && flag {
					return false
				}
				if exp[i] == 't' && !flag {
					return true
				}
			}
		}
	}
	return flag
}

func Not(exp string) bool {
	if len(exp) == 1 {
		return !(exp == "t")
	}
	return !parseBoolExpr(exp)
}

作者:resara
链接:https://leetcode.cn/problems/parsing-a-boolean-expression/solution/golang-fen-jie-by-resara/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

解题思路

动态创建函数

function parseBoolExpr(expression: string): boolean {
    return new Function(
        "t",
        "f",
        "not",
        "and",
        "or",
        "return " +
            expression.replace(/(\!|\&|\|)/g, (a) => {
                const value = translator.get(a);
                return value ?? a;
            })
    )(true, false, not, and, or);
}
const translator = new Map<string, string>([
    ["!", "not"],
    ["&", "and"],
    ["|", "or"],
]);
function not(a: boolean) {
    return !a;
}
function and(...a: boolean[]) {
    let ans = a[0];
    for (const value of a) {
        if (!value) {
            return false;
        }
        ans = ans && value;
    }
    return ans;
}
function or(...a: boolean[]) {
    let ans = a[0];
    for (const value of a) {
        if (value) {
            return true;
        }
        ans = ans || value;
    }
    return ans;
}

作者:masx200
链接:https://leetcode.cn/problems/parsing-a-boolean-expression/solution/by-masx200-5r2r/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值