9.11 给定一个布尔表达式,由0、1、&、|、^等符号组成,以及一个想要的布尔结果result,实现一个函数,算出有几种括号的放法可使该表达式得出result的值。

思路: 枚举分割点递归求解,可用DP优化。

  注意递归终止条件。

  注意 ^ & | 三种情况统计的不同。

import java.util.HashMap;
import java.util.Map;

public class Solution {

    int countR(String terms, boolean result, int start, int end, Map<String, Integer> cache) {
        String key = "" + result + start + end;
        if (cache.containsKey(key)) {
            return cache.get(key);
        }

        if (start == end) {
            if (terms.charAt(start) == ‘0‘) {
                if (result)
                    return 0;
                else
                    return 1;
            } else {
                if (result)
                    return 1;
                else
                    return 0;
            }

        }
        int count = 0;
        if (result) {
            for (int i = start + 1; i < end; i++) {
                char op = terms.charAt(i);
                if (op == ‘&‘) {
                    count += countR(terms, true, start, i - 1, cache) * countR(terms, true, i + 1, end, cache);
                } else if (op == ‘|‘) {
                    count += countR(terms, true, start, i - 1, cache) * countR(terms, true, i + 1, end, cache);
                    count += countR(terms, true, start, i - 1, cache) * countR(terms, false, i + 1, end, cache);
                    count += countR(terms, false, start, i - 1, cache) * countR(terms, true, i + 1, end, cache);

                } else if (op == ‘^‘) {
                    count += countR(terms, true, start, i - 1, cache) * countR(terms, false, i + 1, end, cache);
                    count += countR(terms, false, start, i - 1, cache) * countR(terms, true, i + 1, end, cache);
                }

            }

        } else {
            for (int i = start + 1; i < end; i++) {
                char op = terms.charAt(i);
                if (op == ‘&‘) {
                    count += countR(terms, true, start, i - 1, cache) * countR(terms, false, i + 1, end, cache);
                    count += countR(terms, false, start, i - 1, cache) * countR(terms, true, i + 1, end, cache);
                    count += countR(terms, false, start, i - 1, cache) * countR(terms, false, i + 1, end, cache);

                } else if (op == ‘|‘) {
                    count += countR(terms, false, start, i - 1, cache) * countR(terms, false, i + 1, end, cache);

                } else if (op == ‘^‘) {
                    count += countR(terms, true, start, i - 1, cache) * countR(terms, true, i + 1, end, cache);
                    count += countR(terms, false, start, i - 1, cache) * countR(terms, false, i + 1, end, cache);
                }

            }

        }
        cache.put(key, count);
        return count;
    }

    public static void main(String[] args) {
        String terms = "0^0|1&1^1|0|1";
        boolean result = true;
        Map<String, Integer> cache = new HashMap<String, Integer>();
        System.out.println(new Solution().countR(terms, result, 0, terms.length() - 1, cache));

    }
}
时间: 2024-07-28 14:53:29

9.11 给定一个布尔表达式,由0、1、&、|、^等符号组成,以及一个想要的布尔结果result,实现一个函数,算出有几种括号的放法可使该表达式得出result的值。的相关文章

9.9递归和动态规划(十一)——算出有几种括号的放法可使该表达式得出result值

/** * 攻略:给定一个布尔表达式,由0.1.&.|和^等符号组成,以及一个想要的布尔结果result,实现一个函数,算出有几种括号的放法可使该表达式 * 得出result值. */ 两种方法: 方法一: /** * 思路:迭代整个表达式,将每个运算符当作第一个要加括号的运算符. * @param exp * @param result * @param s:start * @param e:end * @return */ public static int f(String exp,boo

实现一个函数,算出有几种括号的放法可使该表达式得出result值

至此,要解决这个问题,只需反复套用这些递归关系即可.(注意:为了避免代码行不必要的回绕,以及确保代码的可读性,下面的代码使用了非常短的变量名.) public int f(String exp,boolean result,int s,int e) { if(s==e) { if(exp.charAt(s)=='1' && result) { return 1; }else if(exp.charAt(s)=='0'&& !result) { return 1; } ret

条件表达式的短路求值与函数的延迟求值

延迟求值是 .NET的一个很重要的特性,在LISP语言,这个特性是依靠宏来完成的,在C,C++,可以通过函数指针来完成,而在.NET,它是靠委托来完成的.如果不明白什么是延迟求值的同学,我们先看看下面的一段代码: static void TestDelayFunction() { TestDelayFunton1(true,trueFun3); } static void TestDelayFunton1(bool flag , Func<bool> fun ) { if(flag) fun(

关于随机数列,对给定数目的自0开始步长为1的数字序列进行乱序。(可用作洗牌)

1 /** 2  * 数组乱序类 3  * @author noam  4  */ 5 public class NRandom { 6  7     /** 8      * 对给定数目的自0开始步长为1的数字序列进行乱序 9      * @param no 给定数目10      * @return 乱序后的数组11      */12     public static int[] getSequence(int no) {13         int[] sequence = new 

Delphi使用普通类对象创建接受window消息(使用Classes.AllocateHWnd为对象创建一个尺寸为0的窗口,从而有了Handle)good

在delphi中,有时候我们希望对象可以接收windows消息,怎么办呢?因为要接收windows消息起码要有windows Handle,难道要建立的一个可见窗口?那样似乎太差强人意了.delphi提供了一个函数Classes.AllocateHWnd.分析AllocateHWND发现delphi CreateWindowEx一个尺寸为0的窗口,窗口是生成了,Handle也有了,但窗口的消息要处理吧,否则怎么说让对象接收Windows消息呢,但我们都知道类函数和Windows消息处理函数是不一

c++11特性与cocos2d-x 3.0之std::bind与std::function

昨天同事让帮忙写一小功能,才发现cocos2d-x 3.0 和 cocos2d-x 3.0rc0 差别还是相当大的. 发现Label这一个控件,3.0就比rc0版本多了一个创建函数,更为关键的是3.0内的Label锚点是在ccp(0.5,0.5),而一直3.0rc0是ccp(0,0). 累觉不爱.尽管cocos2d-x改变太快,兼容性一次次的暴露出不足,但是,总归是向好的方向进行.于是下载了3.0来玩玩~ cocos new 出新的项目之后,仔细阅读代码,才发现了一句3.0区别于2.0的代码:

柔性数组(结构体最后一个域为0/1数组)

结构体最后的长度为0或1数组的作用(转载) 2012-05-07 17:07:09 其实很 早在看LINUX下就看到这个东西,后来在MFC内存池里同样也看到了类似的东西,还依照MFC写过一个类似的小内存池,(MFC用的是return this + 1)后来在李先静的<系统程序员成长计划>里看到了类似的定义,于是心里想着总结一下,结果发现网上已经有牛人总结的很好了,于是乎就转了过来,谢谢你们 的分享,这是我前进的动力!同时,需要引起注意的:ISO/IEC 9899-1999里面,这么写是非法的,

结构体中最后一个成员为[0]或[1]长度数组(柔性数组成员)的用法

结构体中最后一个成员为[0]长度数组的用法:这是个广泛使用的常见技巧,常用来构成缓冲区.比起指针,用空数组有这样的优势:(1).不需要初始化,数组名直接就是所在的偏移:(2).不占任何空间,指针需要占用int长度空间,空数组不占任何空间.“这个数组不占用任何内存”,意味着这样的结构节省空间:“该数组的内存地址就和它后面的元素地址相同”,意味着无需初始化,数组名就是后面元素的地址,直接就能当指针使用. 这样的写法最适合制作动态buffer,因为可以这样分配空间malloc(sizeof(struc

hdu 2242 无向图/求用桥一分为二后使俩个bcc点权值和之差最小并输出 /缩点+2次新图dfs

题意如标题所述, 先无向图缩点,统计出每个bcc权,建新图,然后一遍dfs生成树,标记出每个点(新图)以及其子孙的权值之和.这样之后就可以dfs2来枚举边(原图的桥),更新最小即可. 调试了半天!原来是建老图时候链式前向星和新图的vector<vector< int>>俩种存图搞乱了!!!不可原谅!哎!愚蠢!愚不可及!提交后1A. 后来百度之后,发现说是用树形dp,看了代码解法,竟然和我的是一样的算法..原来这种算法可以叫树形dp...的确有点dp味道..不过感觉不太浓.. 以后多