解析布尔表达式

题目来源

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

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

  • "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 是以上述形式给出的有效表达式,表示一个布尔值。

思路:递归

  • 如果只有一个字符,即t或f,直接得到结果
  • 如果有多个字符,必然以!&|开头
    • !:将原字符串剔除括号,再进行计算,返回结果的not
    • &:将&括号中的内容拆开,得到多个表达式,分别计算多个表达式并做与运算(这里就是括号很复杂)
    • |同理
class Solution {

    public boolean parseBoolExpr(String expression) {
        if (expression.length() == 1) {
            return expression.equals("t");
        } else {
            char c = expression.charAt(0);
            String subExp = expression.substring(2, expression.length() - 1);
            if (c == '!') {
                return !parseBoolExpr(subExp);
            } else if (c == '&') {
                return parseAnd(subExp);
            } else if (c == '|') {
                return parseOr(subExp);
            }
        }
        return false;
    }

    private boolean parseAnd(String expression) {
        String[] split = split(expression);
        boolean result = parseBoolExpr(split[0]);
        for (int i = 1; i < split.length; i++) {
            result &= parseBoolExpr(split[i]);
            if (!result) {
                return false;
            }
        }
        return result;
    }

    private boolean parseOr(String expression) {
        String[] split = split(expression);
        boolean result = parseBoolExpr(split[0]);
        for (int i = 1; i < split.length; i++) {
            result |= parseBoolExpr(split[i]);
            if (result) {
                return true;
            }
        }
        return result;
    }

    /*
    * 想根据逗号把字符串分开,奈何不会正则
    * 如 f,&(t,t) 分成f、&(t,t)
    * */
    private String[] split(String expression) {
        if (!expression.contains("(")) {
            return expression.split(",");
        }
        String[] splits = new String[10];
        int count = 0;
        String subExp = expression;
        while (true) {
            int dotIndex = subExp.indexOf(',');
            if (dotIndex > 0) {
                String subStr = subExp.substring(0, dotIndex);
                if (!subStr.contains("(")) {
                    splits[count++] = subStr;
                    subExp = subExp.substring(dotIndex + 1);
                    continue;
                }
            }
            int rightIndex = matchBracket(subExp);
            splits[count++] = subExp.substring(0, rightIndex + 1);
            if (rightIndex == subExp.length() - 1) {
                break;
            }
            subExp = subExp.substring(rightIndex + 2);
        }
        String[] ans = new String[count];
        System.arraycopy(splits, 0, ans, 0, count);
        return ans;
    }


    private int matchBracket(String expression) {
        int count = 1;
        int index = 2;
        while (count != 0) {
            if (expression.charAt(index) == '(') {
                count++;
            } else if (expression.charAt(index) == ')') {
                count--;
            }
            index++;
        }
        return index - 1;
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        String expression = "!(&(!(&(f)),&(t),|(f,f,t)))";
//        String expression="|(&(t,f,t),!(t))";
//        String expression="|(f,&(t,t))";
        System.out.println(solution.parseBoolExpr(expression));
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
归下降法是一种自顶向下的语法分析方法,可以用于编写判定布尔表达式的程序。 下面是一个简单的例子,假设我们要编写一个判定布尔表达式的程序,表达式包含以下几种运算符:and、or、not,以及括号。为了方便起见,我们假设表达式中只包含布尔变量和常量(即True和False)。 首先,我们需要定义表达式的文法。假设我们使用以下文法: expr ::= term {or term} term ::= factor {and factor} factor ::= not factor | ( expr ) | bool bool ::= True | False 根据这个文法,我们可以使用归下降法编写一个判定布尔表达式的程序。具体步骤如下: 1. 实现expr函数,用于处理表达式。根据文法,表达式由一个或多个term组成,并且每个term之间使用or运算符连接。因此,我们可以首先调用term函数解析第一个term,然后判断后面是否跟有or运算符,如果有,就继续解析下一个term,直到所有term都解析完毕或者遇到非法输入。 ``` def expr(tokens): result = term(tokens) while tokens and tokens[0] == 'or': tokens.pop(0) result = result or term(tokens) return result ``` 2. 实现term函数,用于处理term。根据文法,term由一个或多个factor组成,并且每个factor之间使用and运算符连接。因此,我们可以首先调用factor函数解析第一个factor,然后判断后面是否跟有and运算符,如果有,就继续解析下一个factor,直到所有factor都解析完毕或者遇到非法输入。 ``` def term(tokens): result = factor(tokens) while tokens and tokens[0] == 'and': tokens.pop(0) result = result and factor(tokens) return result ``` 3. 实现factor函数,用于处理factor。根据文法,factor有三种形式:not factor,( expr ),以及bool。因此,我们需要根据当前token的类型来确定使用哪种处理方式。 ``` def factor(tokens): if tokens[0] == 'not': tokens.pop(0) return not factor(tokens) elif tokens[0] == '(': tokens.pop(0) result = expr(tokens) if tokens[0] != ')': raise SyntaxError('Expected )') tokens.pop(0) return result elif tokens[0] in ['True', 'False']: return tokens.pop(0) == 'True' else: raise SyntaxError('Expected bool or (expr) or not') ``` 4. 实现bool函数,用于处理布尔变量和常量。根据文法,bool只有两种取值:True和False。因此,我们只需要判断当前token是否为True或False即可。 ``` def bool(tokens): if tokens[0] == 'True': tokens.pop(0) return True elif tokens[0] == 'False': tokens.pop(0) return False else: raise SyntaxError('Expected bool') ``` 最后,我们可以将所有函数组合起来,编写一个完整的判定布尔表达式的程序。 ``` def parse_bool_expr(expr_str): tokens = expr_str.split() result = expr(tokens) if tokens: raise SyntaxError('Unexpected token') return result ``` 这个程序可以接受一个布尔表达式字符串作为输入,并返回表达式的计算结果。例如,对于表达式"not (True and False) or (not False and True)",程序将返回True。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值