2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR) 符号组成。
2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR) 符号组成。实现一个函数,算出有几种可使该表达式得出 result 值的括号方法。
福大大 答案2021-06-03:
方法一:递归。
 方法二:动态规划。
代码用golang编写。代码如下:
package main
import "fmt"
func main() {
    express := "1&1&1"
    desired := 1
    ret0 := countEval0(express, desired)
    ret1 := countEval1(express, desired)
    ret2 := countEval2(express, desired)
    fmt.Println(ret0, ret1, ret2)
}
func countEval0(express string, desired int) int {
    if express == "" {
        return 0
    }
    N := len(express)
    dp := make([][]*Info, N)
    for i := 0; i < N; i++ {
        dp[i] = make([]*Info, N)
    }
    allInfo := ff(express, 0, len(express)-1, dp)
    return twoSelectOne(desired == 1, allInfo.t, allInfo.f)
}
type Info struct {
    t int
    f int
}
func twoSelectOne(c bool, a int, b int) int {
    if c {
        return a
    } else {
        return b
    }
}
// 限制:
// L...R上,一定有奇数个字符
// L位置的字符和R位置的字符,非0即1,不能是逻辑符号!
// 返回str[L...R]这一段,为true的方法数,和false的方法数
func ff(str string, L int, R int, dp [][]*Info) *Info {
    if dp[L][R] != nil {
        return dp[L][R]
    }
    t := 0
    f := 0
    if L == R {
        t = twoSelectOne(str[L] == '1', 1, 0)
        f = twoSelectOne(str[L] == '0', 1, 0)
    } else { // L..R >=3
        // 每一个种逻辑符号,split枚举的东西
        // 都去试试最后结合
        for split := L + 1; split < R; split += 2 {
            leftInfo := ff(str, L, split-1, dp)
            rightInfo := ff(str, split+1, R, dp)
            a := leftInfo.t
            b := leftInfo.f
            c := rightInfo.t
            d := rightInfo.f
            switch str[split] {
            case '&':
                t += a * c
                f += b*c + b*d + a*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] = &Info{t, f}
    return dp[L][R]
}
func countEval1(express string, desired int) int {
    if express == "" {
        return 0
    }
    return f(express, desired, 0, len(express)-1)
}
func f(str string, desired int, L int, R int) int {
    if L == R {
        if str[L] == '1' {
            return desired
        } else {
            return desired ^ 1
        }
    }
    res := 0
    if desired == 1 {
        for i := L + 1; i < R; i += 2 {
            switch str[i] {
            case '&':
                res += f(str, 1, L, i-1) * f(str, 1, i+1, R)
                break
            case '|':
                res += f(str, 1, L, i-1) * f(str, 0, i+1, R)
                res += f(str, 0, L, i-1) * f(str, 1, i+1, R)
                res += f(str, 1, L, i-1) * f(str, 1, i+1, R)
                break
            case '^':
                res += f(str, 1, L, i-1) * f(str, 0, i+1, R)
                res += f(str, 0, L, i-1) * f(str, 1, i+1, R)
                break
            }
        }
    } else {
        for i := L + 1; i < R; i += 2 {
            switch str[i] {
            case '&':
                res += f(str, 0, L, i-1) * f(str, 1, i+1, R)
                res += f(str, 1, L, i-1) * f(str, 0, i+1, R)
                res += f(str, 0, L, i-1) * f(str, 0, i+1, R)
                break
            case '|':
                res += f(str, 0, L, i-1) * f(str, 0, i+1, R)
                break
            case '^':
                res += f(str, 1, L, i-1) * f(str, 1, i+1, R)
                res += f(str, 0, L, i-1) * f(str, 0, i+1, R)
                break
            }
        }
    }
    return res
}
func countEval2(express string, desired int) int {
    if express == "" {
        return 0
    }
    N := len(express)
    dp := make([][][]int, 2)
    for i := 0; i < 2; i++ {
        dp[i] = make([][]int, N)
        for j := 0; j < N; j++ {
            dp[i][j] = make([]int, N)
        }
    }
    dp[0][0][0] = twoSelectOne(express[0] == '0', 1, 0)
    dp[1][0][0] = dp[0][0][0] ^ 1
    for i := 2; i < len(express); i += 2 {
        dp[0][i][i] = twoSelectOne(express[i] == '1', 0, 1)
        dp[1][i][i] = twoSelectOne(express[i] == '0', 0, 1)
        for j := i - 2; j >= 0; j -= 2 {
            for k := j; k < i; k += 2 {
                if express[k+1] == '&' {
                    dp[1][j][i] += dp[1][j][k] * dp[1][k+2][i]
                    dp[0][j][i] += (dp[0][j][k]+dp[1][j][k])*dp[0][k+2][i] + dp[0][j][k]*dp[1][k+2][i]
                } else if express[k+1] == '|' {
                    dp[1][j][i] += (dp[0][j][k]+dp[1][j][k])*dp[1][k+2][i] + dp[1][j][k]*dp[0][k+2][i]
                    dp[0][j][i] += dp[0][j][k] * dp[0][k+2][i]
                } else {
                    dp[1][j][i] += dp[0][j][k]*dp[1][k+2][i] + dp[1][j][k]*dp[0][k+2][i]
                    dp[0][j][i] += dp[0][j][k]*dp[0][k+2][i] + dp[1][j][k]*dp[1][k+2][i]
                }
            }
        }
    }
    return dp[desired][0][N-1]
}
执行结果如下:
 
2021-06-03:布尔运算。给定一个布尔表达式和一个期望的布尔结果 result,布尔表达式由 0 (false)、1 (true)、& (AND)、 | (OR) 和 ^ (XOR) 符号组成。的更多相关文章
- 2021.11.03 P6175 无向图的最小环问题
		
2021.11.03 P6175 无向图的最小环问题 P6175 无向图的最小环问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 给定一张无向图,求图中一个至少包含 33 ...
 - 2021.05.03 T3 数字
		
2021.05.03 T3 数字 问题描述 一个数字被称为好数字当他满足下列条件: 1. 它有**2*n**个数位,n是正整数(允许有前导0) 2. 构成它的每个数字都在给定的数字集合S中. 3. 它 ...
 - 2021.08.03 BZOJ 疯狂的馒头(并查集)
		
2021.08.03 BZOJ 疯狂的馒头(并查集) 疯狂的馒头 - 题目 - 黑暗爆炸OJ (darkbzoj.tk) 重点: 1.并查集的神奇运用 2.离线化 题意: 给一个长为n的序列,进行m次 ...
 - 2021.08.03 P1197 星球大战(并查集)
		
2021.08.03 P1197 星球大战(并查集) [P1197 JSOI2008]星球大战 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.可以离线处理.把在线变为离 ...
 - android 1.6 launcher研究之自定义ViewGroup (转 2011.06.03(二)——— android 1.6 launcher研究之自定义ViewGroup )
		
2011.06.03(2)——— android 1.6 launcher研究之自定义ViewGroup2011.06.03(2)——— android 1.6 launcher研究之自定义ViewG ...
 - 在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作。一次移动操作指用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。现给定起始字符串start和结束字符串end,请编写代码,当且仅当存在一系列移动操作使得start可以转换成end时, 返回True。
		
在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作.一次移动操作指用一个"LX"替换一个"XL ...
 - 给定一个正整数,实现一个方法求出离该整数最近的大于自身的 换位数 <把一个整数各个数位进行全排列>
		
"""给定一个正整数,实现一个方法求出离该整数最近的大于自身的 换位数 -> 把一个整数各个数位进行全排列""" # 使用 permu ...
 - 2021.11.03 P2886 [USACO07NOV]Cow Relays G(矩阵+floyed)
		
2021.11.03 P2886 [USACO07NOV]Cow Relays G(矩阵+floyed) [P2886 USACO07NOV]Cow Relays G - 洛谷 | 计算机科学教育新生 ...
 - 转载    精进不休 .NET 4.0 (5) - C# 4.0 新特性之并行运算(Parallel)   https://www.cnblogs.com/webabcd/archive/2010/06/03/1750449.html
		
精进不休 .NET 4.0 (5) - C# 4.0 新特性之并行运算(Parallel) 介绍C# 4.0 的新特性之并行运算 Parallel.For - for 循环的并行运算 Parall ...
 - HTML & CSS & JavaScript 从一个表格到一个灰阶颜色表 03
		
工具1:HBuilder X 1.9.9.20190522 工具2:火狐浏览器 67.0.4 (64 位) 其实,我还想使用表格,做一个这样的颜色表,如下图所示: 如果按照之前的做法,把每一种颜色都列 ...
 
随机推荐
- Linux高并发服务器之Linux多线程开发
			
本文源自C++高薪面试项目的学习笔记,主要记录Liunx多线程的学习,主要知识点是线程概述等基础概念以外,还有线程相关Liunx系统函数以及对应练手代码,除此之外还有线程同步问题的讲解以及实战多线程买 ...
 - K8S 性能优化 - OS sysctl 调优
			
前言 K8S 性能优化系列文章,本文为第一篇:OS sysctl 性能优化参数最佳实践. 参数一览 sysctl 调优参数一览 # Kubernetes Settings vm.max_map_cou ...
 - Python练习--简单习题(也是一看就能够写出来的代码)
			
Python计算列表数字的和 数字范围内的所有偶数(append) 移除列表中的多个元素(remove) 如何实现对列表的去重 如何对简单列表进行排序 Python实现学生的排序11)
 - Spring--第三方bean管理
			
第三方bean管理 管理第三方的bean的话,是不能在配置文件里面写这个注解的: 他表示的是,扫描你当前文件里面的bean,是可以直接获取到的. 那么,对于第三方的bean,我们可以这么做: 在配置文 ...
 - 实践Pytorch中的模型剪枝方法
			
摘要:所谓模型剪枝,其实是一种从神经网络中移除"不必要"权重或偏差的模型压缩技术. 本文分享自华为云社区<模型压缩-pytorch 中的模型剪枝方法实践>,作者:嵌入式 ...
 - 使用float进行比较问题处理
			
float compare Abstract 使用float数据进行精确计算和比较,可能由于精度问题导致程序逻辑异常. Explanation 使用float数据进行比较,计算机表达double和fl ...
 - uni-app云开发入门
			
云函数 首先创建一个uniapp项目,创建项目时选择启用uniCloud云开发. 创建项目成功后,按照下面的步骤进行开发. 创建云函数 1.关联云服务器 2.创建云函数 一个云函数可以看成是一个后 ...
 - 千亿参数开源大模型 BLOOM 背后的技术
			
假设你现在有了数据,也搞到了预算,一切就绪,准备开始训练一个大模型,一显身手了,"一朝看尽长安花"似乎近在眼前 -- 且慢!训练可不仅仅像这两个字的发音那么简单,看看 BLOOM ...
 - flutter ui---->一些类QQ的实现
			
整理一下比较有意思的类QQ的UI实现.Nothing that has meaning is easy. Easy doesn't enter into grown-up life. darken t ...
 - GitHub+Hexo 搭建博客网站
			
Hexo是一款基于Node.js的静态博客框架,依赖少易于安装使用,可以方便的生成静态网页托管在GitHub和Heroku上,是搭建博客的首选框架. 配置Github root@hello:~/cby ...