问题描述:

给定一个只由 0(假)、1(真)、&(逻辑与)、|(逻辑或)和^(异或)五种字符组成的字符串express,再给定一个布尔值 desired。返回express能有多少种组合方式,可以达到desired的结果。
【举例】
       express="1^0|0|1",desired=false
        只有 1^((0|0)|1)和 1^(0|(0|1))的组合可以得到 false,返回 2。

express="1",desired=false无组合则可以得到false,返回0。

思路

在进行不同思路得出答案之前,必须验证输入的字符串是否符合规范。

思路一:在输入字符串满足条件的基础上,定义方法 f(char[] str, boolean desired, int L, int R)返回期待desired的方法数。i位置尝试L..R范围上的每一个逻辑符号,都是最后结合的。

思路二:使用动态规划的思想。定义两张正方形的二维表tMap和fMap,边长为输入字符串字符的长度。我们分析题目可知L<=R的,故两张正方形二维表的右下角部分不填数字。并且满足条件的字符串必须字符个数为奇数,偶数位置必须是1或者0,奇数位置必须是&、|和^,我们得知两张二维表的奇数行奇数列全部不填数字。

我们可以首先填写两张二维表左上到右下对角线的数字,再根据思路一分析的情况快速计算出两张二维表其他位置上的数字,。tMap[0][N - 1] :或fMap[0][N - 1]即为我们所需的答案。

代码

判断输入的字符串是否符合规范

    //判断输入的字符串是否符合规范public static boolean isValid(char[] exp) {if ((exp.length & 1) == 0) {return false;}for (int i = 0; i < exp.length; i = i + 2) {if ((exp[i] != '1') && (exp[i] != '0')) {return false;}}for (int i = 1; i < exp.length; i = i + 2) {if ((exp[i] != '&') && (exp[i] != '|') && (exp[i] != '^')) {return false;}}return true;}

思路一代码:

    public static int num1(String express, boolean desired) {if (express == null || express.equals("")) {return 0;}char[] exp = express.toCharArray();if (!isValid(exp)) {return 0;}return f(exp, desired, 0, exp.length - 1);}//exp[L..R] 返回期待desired的方法数//潜台词:L  R 必须是偶数位置public static int f(char[] str, boolean desired, int L, int R) {if (L == R) {if (str[L] == '1') {return desired ? 1 : 0;} else {return desired ? 0 : 1;}}//L..Rint res = 0;if (desired) {//期待为true//i位置尝试L..R范围上的每一个逻辑符号,都是最后结合的for (int i = L + 1; i < R; i += 2) {//exp[i] 一定压中逻辑符号switch (str[i]) {case '&':res += f(str, true, L, i - 1) * f(str, true, i + 1, R);break;case '|':res += f(str, true, L, i - 1) * f(str, false, i + 1, R);res += f(str, false, L, i - 1) * f(str, true, i + 1, R);res += f(str, true, L, i - 1) * f(str, true, i + 1, R);break;case '^':res += f(str, true, L, i - 1) * f(str, false, i + 1, R);res += f(str, false, L, i - 1) * f(str, true, i + 1, R);break;}}} else {//期待为falsefor (int i = L + 1; i < R; i += 2) {switch (str[i]) {case '&':res += f(str, false, L, i - 1) * f(str, true, i + 1, R);res += f(str, true, L, i - 1) * f(str, false, i + 1, R);res += f(str, false, L, i - 1) * f(str, false, i + 1, R);break;case '|':res += f(str, false, L, i - 1) * f(str, false, i + 1, R);break;case '^':res += f(str, true, L, i - 1) * f(str, true, i + 1, R);res += f(str, false, L, i - 1) * f(str, false, i + 1, R);break;}}}return res;}

思路二代码:

    public static int dp(String s, boolean d) {char[] str = s.toCharArray();int N = str.length;int[][] tMap = new int[N][N];int[][] fMap = new int[N][N];for (int i = 0; i < N; i += 2) {tMap[i][i] = str[i] == '1' ? 1 : 0;fMap[i][i] = str[i] == '0' ? 1 : 0;}for (int row = N - 3; row >= 0; row = row - 2) {for (int col = row + 2; col < N; col = col + 2) {for (int i = row + 1; i < col; i += 2) {switch (str[i]) {case '&':tMap[row][col] += tMap[row][i - 1] * tMap[i + 1][col];break;case '|':tMap[row][col] += tMap[row][i - 1] * fMap[i + 1][col];tMap[row][col] += fMap[row][i - 1] * tMap[i + 1][col];tMap[row][col] += tMap[row][i - 1] * tMap[i + 1][col];break;case '^':tMap[row][col] += tMap[row][i - 1] * fMap[i + 1][col];tMap[row][col] += fMap[row][i - 1] * tMap[i + 1][col];break;}switch (str[i]) {case '&':fMap[row][col] += tMap[row][i - 1] * fMap[i + 1][col];fMap[row][col] += fMap[row][i - 1] * tMap[i + 1][col];fMap[row][col] += fMap[row][i - 1] * fMap[i + 1][col];break;case '|':fMap[row][col] += fMap[row][i - 1] * fMap[i + 1][col];break;case '^':fMap[row][col] += tMap[row][i - 1] * fMap[i + 1][col];fMap[row][col] += fMap[row][i - 1] * fMap[i + 1][col];break;}}}}return d ? tMap[0][N - 1] : fMap[0][N - 1];}public static int num2(String express, boolean desired) {if (express == null || express.equals("")) {return 0;}char[] exp = express.toCharArray();if (!isValid(exp)) {return 0;}int[][] t = new int[exp.length][exp.length];int[][] f = new int[exp.length][exp.length];t[0][0] = exp[0] == '0' ? 0 : 1;f[0][0] = exp[0] == '1' ? 0 : 1;for (int i = 2; i < exp.length; i += 2) {t[i][i] = exp[i] == '0' ? 0 : 1;f[i][i] = exp[i] == '1' ? 0 : 1;for (int j = i - 2; j >= 0; j -= 2) {for (int k = j; k < i; k += 2) {if (exp[k + 1] == '&') {t[j][i] += t[j][k] * t[k + 2][i];f[j][i] += (f[j][k] + t[j][k]) * f[k + 2][i] + f[j][k] * t[k + 2][i];} else if (exp[k + 1] == '|') {t[j][i] += (f[j][k] + t[j][k]) * t[k + 2][i] + t[j][k] * f[k + 2][i];f[j][i] += f[j][k] * f[k + 2][i];} else {t[j][i] += f[j][k] * t[k + 2][i] + t[j][k] * f[k + 2][i];f[j][i] += f[j][k] * f[k + 2][i] + t[j][k] * t[k + 2][i];}}}}return desired ? t[0][t.length - 1] : f[0][f.length - 1];}public static void main(String[] args) {String express = "1^0&0|1&1^0&0^1|0|1&1";boolean desired = true;System.out.println(num1(express, desired));System.out.println("===============");System.out.println(num2(express, desired));}

给定一个只由 0、1、、|和^五种字符组成的字符串express,再给定一个布尔值 desired。返回express能有多少种组合方式,可以达到desired的结果。相关推荐

  1. c语言字符为0和1,//C语言:将一个由字符0和1组成的表示二进制数的字符串,转换成相应的十进制数返回。...

    //函数fun:将一个由字符0和1组成的表示二进制数的字符串,转换成相应的十进制数返回. #include #pragma warning (disable:4996) #define N 16 /* ...

  2. 求一个只包含0、1的矩阵中只包含1的最大子矩阵大小

    题目描述: 给定一个无序矩阵,其中只有1和0两种值,求只含有1的最大正方形的大小. 例如给定如下矩阵: 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 public c ...

  3. java去除字符串中最后一个字符_java中字符串如何去除最后一个字符方法

    java中字符串如何去除最后一个字符方法. 方法有很多.不过如果只是个测试,那哪种都可以. 最简单易懂的方法 利用substring()与length() String str = "abc ...

  4. python判断字符串包含某个字符_python判断字符串是否包含另一个字符串

    Python判断一个字符串是否包含子串的方法有很多,下面介绍几种方法. 1.使用成员操作符 in>>> s='nihao,shijie' >>> t='nihao' ...

  5. python设置一个初始为0的计数器_如何为python列表的每个元素实现一个计数器?...

    使用 Python 3.4 我有一种方法可行,但我认为可能有更好的方法. 我希望有一个方法expand()的列表,它从列表中选择一个随机元素,但每次选择该元素时,计数器都会递增.我尝试继承str以便能 ...

  6. python编写一个程序、计算字符串中子串出现的次数_急求。。。C语言实现,计算字符串中子串出现的次数,就是先输入一个字符串,再输入一个上面字符串中存在...

    展开全部 #include #include void main() { char str1[20], str2[20], *p1, *p2; int sum=0; printf("Plea ...

  7. java字符串去掉最后一个逗号_java拼接字符串时去掉最后一个多余逗号的方法

    java拼接字符串时去掉最后一个多余逗号的方法 本文实例讲述了java拼接字符串时去掉最后一个多余逗号的方法.分享给大家供大家参考.具体分析如下: 先看下面这段代码: for (int t = 0; ...

  8. python中指定最后一个字符_如何从Python字符串中删除最后一个字符?

    如何从Python字符串中删除最后一个字符? Python支持负索引切片和正切片.负索引从  -1 到-(iterable_length)开始.我们将使用负切片从可迭代对象的末尾获取元素. 索引  - ...

  9. 一个或多个空格、TAB等分隔符隔开的字符串

    这里写自定义目录标题 QString header=aFileContent.at(0);//第1行是表头 //一个或多个空格.TAB等分隔符隔开的字符串, 分解为一个StringList QStri ...

最新文章

  1. sql查询每个学生的最高成绩mysql语句
  2. CTFshow 命令执行 web57
  3. MongoDB数据库(3.mongodb数据库的高级查询)
  4. oracle导出字符集命令,Oracle数据的导出及导入实现
  5. security中的@EnableGlobalMethodSecurity注解详解
  6. Java Web开发Session超时设置
  7. PLSQL 使用教程
  8. 微信小程序从云开发到上线
  9. 用python计算工程量_总算懂了工程造价工程量计算方法
  10. 一键快速打开IE的Internet选项->连接->局域网设置
  11. 牧月科技完成近5000万元天使轮融资,为无人驾驶货运物流提供解决方案
  12. 2017物联网蓬勃发展,看各领域巨头如何抢先机占山头
  13. 信息指纹及其应用3例
  14. 求一段字符串内最长的非空子字符串的长度(实例)
  15. 微信小程序Timeline时间线效果实现
  16. 【供应链架构day6】百世零售供应链架构之道:全渠道的落地与挑战
  17. 2022字节跳动数仓实习面经(2、3面、hr面)
  18. git获取代码,拉取最新代码,更新代码等
  19. 成长笔记1:三层难度步步进阶,我用21部原版动画,带娃积累2000词汇
  20. 历史上的三次数学危机

热门文章

  1. Js 根据年月获取这月或者年的开始日期和结束日期
  2. PowerPoint 不能从所选文件插入视频 解决办法
  3. word——图表题注及图表目录、公式编号及交叉引用
  4. 5G切片 NFV SDN 架构笔记
  5. 搭建velocity开发环境
  6. mac笔记本中找不到library文件夹的解决办法
  7. 量子隐形传态和超密编码
  8. windows下搭建mysql集群_Windows下搭建MySQL集群
  9. 2009年11月26日 博客更新公告!
  10. Delphi FastReport 打印条码