1106 . 解析布尔表达式
思路:栈
1、遍历表达式字符串
2、只要没遇到右括号则全都入栈
3、遇到了右括号则说明要处理在这个右括号之前的字符的逻辑了。
4、处理逻辑很简单,就是统计里面的f和t的数量,或者说存不存在。也就是对f和t累加或者各自标记为1都行,方便后面处理左括号前面的“运算符”的逻辑。
5、拿到运算符,对已记录的t和f做相应的运算。
如果是 '!' 则对栈顶元素取反后将其入栈
如果是 '|' 则判断当前t有没有标记过,有就直接将t入栈,否则f入栈
如果是 '&' 则判断当前f有没有标记过,有就直接f入栈,否则t入栈
6、循环运算到最后之后只剩下一个字符,要么是t要么是f。直接返回栈顶是否等于t/f就行了
func parseBoolExpr(expression string) bool {
sk := []rune{}
for _, c := range expression {
if c != ')' { // 不是右括号统统入栈
sk = append(sk, c)
} else if c == ')' { // 遇到右括号,要处理前面的逻辑了
f,t := 0, 0 // 用f和t来记录其值
for sk[len(sk)-1] != '('{ // 在遍历到左括号之前都不停呢
if sk[len(sk)-1] == 't' {
t++ // 或者这里只标记为1也行 , t = 1
} else if sk[len(sk)-1] == 'f' {
f++ // 或者这里只标记为1页行, f = 1
}
sk = sk[:len(sk)-1] // 弹出t和f
}
sk = sk[:len(sk)-1] // 弹出左括号
op := sk[len(sk)-1] // 得到操作符
sk = sk[:len(sk)-1] // 弹出操作符
switch op {
case '!': {
if f >= 1 { // 对其取反 ,如果上面标记为1,那么下面这些大于等于号改为等号=就可以了
sk = append(sk, 't')
} else if t >= 1 { // 对其取反
sk = append(sk, 'f')
}
}
case '|': { // 只要当前存在一个为true则是true
if t >= 1 {
sk = append(sk, 't')
} else {
sk = append(sk, 'f')
}
}
case '&': { // 只要存在一个false,就false
if f >= 1 {
sk = append(sk, 'f')
} else {
sk = append(sk, 't')
}
}
}
}
}
return sk[len(sk)-1] == 't'
}