根據(jù)題意我們可以知道,一個運算符一定會跟隨一對括號,比如 !(t)拷邢。
所以我們可以直接判斷expression[0],得到最外層的運算符屎慢,根據(jù)運算符處理內層的表達式瞭稼。
- 如果不是運算符,肯定就是 't'或者 'f' 直接判斷即可
- 如果是't'腻惠,里面要么就是單一的字符环肘,要么就是一個新的表達式。再調用parseBoolExpr解析并取反即可集灌。
- 如果是 '&' 或者 '|'悔雹, 需要對里面每個表達式分別求解。通過括號匹配欣喧,拿到第一個'('匹配的')'里面的表達式腌零,再通過 parseBoolExpr 計算出值。
- 在計算 '&' 的時候唆阿,如果有一個值為false益涧,可以提前結束計算。同理酷鸦,在計算'|'時饰躲, 如果有一個值為true,也可以提前結束計算。
完整代碼見下:
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)
}