【刷题篇】布尔运算

一、题目

OJ链接

给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR) 符号组成。实现一个函数,算出有几种可使该表达式得出 result 值的括号方法。

在这里插入图片描述

二、题解

范围尝试模型

2.1 递归

在这里插入图片描述

public static class Info{
     public int t;
     public int f;
     public Info(int t, int f) {
         this.t = t;
         this.f = f;
     }
 }
//L...R 一共有奇数个字符
 //L和R位置的字符,非0即1
//返回str[L..R] 为true和false的方法数
 public static Info func(char[] str,int L ,int R){
     int t=0;
     int f=0;
   if(L==R){
      t=str[L]=='1'?1:0;
      f=str[L]=='0'?1:0;
   } else {

       //spilt是逻辑符号的位置
       for (int spilt = L+1; spilt <R ; spilt+=2) {
           Info left=func(str,L,spilt-1);
           Info right=func(str,spilt+1,R);
           int a=left.t;
           int b=left.f;
           int c=right.t;
           int d=right.f;
           switch (str[spilt]){
               case '&':
                   t+=a*c;
                   f+=a*d+b*c+b*d;
                   break;
               case '|':
                   t+=a*c+a*d+b*c;
                   f+=b*d;
                   break;
               case '^':
                   t+=a*d+b*c;
                   f+=a*c+b*d;
                   break;
           }
       }
   }
       return new Info(t,f);
 }

    public static int countEval1(String s, int result) {
    if(s==null||s.length()==0){
        return 0;
    }
    char[] str=s.toCharArray();
    Info ret=func(str,0,str.length-1);
    if(result==0){
        return ret.f;
    }else {
        return ret.t;
    }
    }

2.2 记忆化搜索

在递归的基础上添加一个缓存表,避免重复计算

public static class Info{
     public int t;
     public int f;
     public Info(int t, int f) {
         this.t = t;
         this.f = f;
     }
 }
public static Info func2(char[] str,int L ,int R,Info[][] dp){
     if(dp[L][R]!=null){
         return dp[L][R];
     }
        int t=0;
        int f=0;
        if(L==R){
            t=str[L]=='1'?1:0;
            f=str[L]=='0'?1:0;
        } else {

            for (int spilt = L+1; spilt <R ; spilt+=2) {

                Info left=func2(str,L,spilt-1,dp);
                Info right=func2(str,spilt+1,R,dp);
                int a=left.t;
                int b=left.f;
                int c=right.t;
                int d=right.f;
                switch (str[spilt]){
                    case '&':
                        t+=a*c;
                        f+=a*d+b*c+b*d;
                        break;
                    case '|':
                        t+=a*c+a*d+b*c;
                        f+=b*d;
                        break;
                    case '^':
                        t+=a*d+b*c;
                        f+=a*c+b*d;
                        break;
                }
            }
        }
        dp[L][R]=new Info(t,f);
        return dp[L][R];
    }
    public static int countEval2(String s, int result) {
        if(s==null||s.length()==0){
            return 0;
        }
        char[] str=s.toCharArray();
        int N=str.length;
        Info[][] dp=new Info[N][N];
        Info ret=func2(str,0,str.length-1,dp);
        if(result==0){
            return ret.f;
        }else {
            return ret.t;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值