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

/**

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

* 得出result值。

*/

两种方法:

方法一:

	/**
	 * 思路:迭代整个表达式,将每个运算符当作第一个要加括号的运算符。
	 * @param exp
	 * @param result
	 * @param s:start
	 * @param e:end
	 * @return
	 */
	public static int f(String exp,boolean result,int s,int e){
		if(s==e){
			if(exp.charAt(s)=='1'&&result)
				return 1;
			if(exp.charAt(s)=='0'&&!result)
				return 1;
			return 0;
		}

		int c=0;
		if(result){
			for(int i=s+1;i<=e;i+=2){
				if(exp.charAt(i)=='&'){
					c+=f(exp,true,s,i-1)*f(exp,true,i+1,e);
				}else if(exp.charAt(i)=='|'){
					c+=f(exp,true,s,i-1)*f(exp,true,i+1,e);
					c+=f(exp,false,s,i-1)*f(exp,true,i+1,e);
					c+=f(exp,true,s,i-1)*f(exp,false,i+1,e);
				}else if(exp.charAt(i)=='^'){
					c+=f(exp,true,s,i-1)*f(exp,false,i+1,e);
					c+=f(exp,false,s,i-1)*f(exp,true,i+1,e);
				}
			}
		}else{
			for(int i=s+1;i<=e;i+=2){
				if(exp.charAt(i)=='&'){
					c+=f(exp,true,s,i-1)*f(exp,false,i+1,e);
					c+=f(exp,false,s,i-1)*f(exp,true,i+1,e);
					c+=f(exp,false,s,i-1)*f(exp,false,i+1,e);
				}else if(exp.charAt(i)=='|'){
					c+=f(exp,false,s,i-1)*f(exp,false,i+1,e);
				}else if(exp.charAt(i)=='^'){
					c+=f(exp,true,s,i-1)*f(exp,true,i+1,e);
					c+=f(exp,false,s,i-1)*f(exp,false,i+1,e);
				}
			}
		}

		return c;
	}	

方法二:

	//动态规划
	/**
	 * 思路:缓存不同表达式的结果,避免多次用到同一个exp的值时需要重算。对expression和result进行缓存。
	 * @param exp
	 * @param result
	 * @param s
	 * @param e
	 * @param map
	 * @return
	 */
	public static int ff(String exp,boolean result,int s,int e,HashMap<String,Integer> map){
		String key=""+result+s+e;//注意加""的位置,应加在前面,表示为字符串的拼接。否则,则表示值先相加,再转字符串
		if(map.containsKey(key))
			return map.get(key);

		int c=0;
		if(result){
			for(int i=s+1;i<=e;i+=2){
				if(exp.charAt(i)=='&'){
					c+=f(exp,true,s,i-1)*f(exp,true,i+1,e);
				}else if(exp.charAt(i)=='|'){
					c+=f(exp,true,s,i-1)*f(exp,true,i+1,e);
					c+=f(exp,false,s,i-1)*f(exp,true,i+1,e);
					c+=f(exp,true,s,i-1)*f(exp,false,i+1,e);
				}else if(exp.charAt(i)=='^'){
					c+=f(exp,true,s,i-1)*f(exp,false,i+1,e);
					c+=f(exp,false,s,i-1)*f(exp,true,i+1,e);
				}
			}
		}else{
			for(int i=s+1;i<=e;i+=2){
				if(exp.charAt(i)=='&'){
					c+=f(exp,true,s,i-1)*f(exp,false,i+1,e);
					c+=f(exp,false,s,i-1)*f(exp,true,i+1,e);
					c+=f(exp,false,s,i-1)*f(exp,false,i+1,e);
				}else if(exp.charAt(i)=='|'){
					c+=f(exp,false,s,i-1)*f(exp,false,i+1,e);
				}else if(exp.charAt(i)=='^'){
					c+=f(exp,true,s,i-1)*f(exp,true,i+1,e);
					c+=f(exp,false,s,i-1)*f(exp,false,i+1,e);
				}
			}
		}
		map.put(key, c);
		return c;	

	}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-03 11:01:11

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

实现一个函数,算出有几种括号的放法可使该表达式得出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

9.11 给定一个布尔表达式,由0、1、&amp;、|、^等符号组成,以及一个想要的布尔结果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 = "" + re

9.9递归和动态规划(六)——打印n对括号的所有有效组合(即左右括号正确配对)

/** * 功能:打印n对括号的所有有效组合(即左右括号正确配对). */ 两种方法: 方法一: /** * 思路:在括号的最前面或者原有的每对括号中面插入一对括号. 至于其它任何位置.比方字符串的末尾,都会跟之前的情况反复. * 注意:将字符串放进结果列表之前.必须检查列表有无反复. * @param remaining * @return */ public static HashSet<String> generateParens(int remaining){ HashSet<S

9.9递归和动态规划(六)——打印n对括号的全部有效组合(即左右括号正确配对)

/** * 功能:打印n对括号的全部有效组合(即左右括号正确配对). */ 两种方法: 方法一: /** * 思路:在括号的最前面或者原有的每对括号里面插入一对括号.至于其他任意位置,比如字符串的末尾,都会跟之前的情况重复. * 注意:将字符串放进结果列表之前,必须检查列表有无重复. * @param remaining * @return */ public static HashSet<String> generateParens(int remaining){ HashSet<St

利用递归和动态规划来求解组合数

组合数定义:从m个不同元素中,任取n(n≤m)个元素并成一组,叫做从m个不同元素中取出n个元素的一个组合:从m个不同元素中取出n(n≤m)个元素的所有组合的个数,叫做从m个不同元素中取出n个元素的组合数. 下面是一种比较通俗的计算公式: 其递归公式为: c(n,m)=c(n-1,m-1)+c(n-1,m) 下面是c++实现该递归算法: #include <iostream> #include <stdlib.h> #define EXIT -1 using namespace st

算法初级面试题08——递归和动态规划的精髓、阶乘、汉诺塔、子序列和全排列、母牛问题、逆序栈、最小的路径和、数组累加成指定整数、背包问题

第八课主要介绍递归和动态规划 介绍递归和动态规划 暴力递归: 1,把问题转化为规模缩小了的同类问题的子问题 2,有明确的不需要继续进行递归的条件(base case) 3,有当得到了子问题的结果之后的决策过程 4,不记录每一个子问题的解 动态规划 1,从暴力递归中来 2,将每一个子问题的解记录下来,避免重复计算 3,把暴力递归的过程,抽象成了状态表达 4,并且存在化简状态表达,使其更加简洁的可能 图灵引入的是:我不知道怎么算,但是我知道怎么试.知道怎么暴力破解出来. 要学会,练习懂得怎么尝试.

fibonacci数列的两种求解方式:基础递归VS动态规划

/* * 基础解法,按照递归方法求解,该算法的运算时间是指数级增长的 * 这种算法对于相似的子问题进行了重复的计算,因此不是一种高效的算法 */ public class FibonacciRecursion { //-----------计算Fibonacci数列值的递归函数-------------- public static int fib(int n){ if(n==1||n==2){//序列中第1,2个数为1 return 1; } return fib(n-1)+fib(n-2);

70. Climbing Stairs【leetcode】递归,动态规划,java,算法

You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? Note: Given n will be a positive integer. 题目分析:每次只能走1或2步,问n步的话有多少中走法???? 可以用动态规划和递归解

左神算法第八节课:介绍递归和动态规划(汉诺塔问题;打印字符串的全部子序列含空;打印字符串的全排列,无重复排列;母牛数量;递归栈;数组的最小路径和;数组累加和问题,一定条件下最大值问题(01背包))

暴力递归: 1,把问题转化为规模缩小了的同类问题的子问题 2,有明确的不需要继续进行递归的条件(base case) 3,有当得到了子问题的结果之后的决策过程 4,不记录每一个子问题的解 动态规划 1,从暴力递归中来 2,将每一个子问题的解记录下来,避免重复计算 3,把暴力递归的过程,抽象成了状态表达 4,并且存在化简状态表达,使其更加简洁的可能 一:递归 1. 汉诺塔问题 汉诺塔问题(不能大压小,只能小压大),打印n层汉诺塔从最左边移动到最右边的全部过程. 左中右另称为 from.to.hel