Counting Boolean Parenthesizations

You are given a boolean expression consisting of a string of the symbols 'true', 'false', 'and', 'or', and 'xor'. Count the number of ways to parenthesize the expression such that it will evaluate to true. For example, there are 2 ways to parenthesize 'true and false xor true' such that it evaluates to true.

 

Given a boolean expression with following symbols.

Symbols
    'T' ---> true 
    'F' ---> false 

And following operators filled between symbols

Operators
    &   ---> boolean AND
    |   ---> boolean OR
    ^   ---> boolean XOR 

Count the number of ways we can parenthesize the expression so that the value of expression evaluates to true.

 

Examples:

Input: symbol[]    = {T, F, T}
       operator[]  = {^, &}
Output: 2
The given expression is "T ^ F & T", it evaluates true
in two ways "((T ^ F) & T)" and "(T ^ (F & T))"

Input: symbol[]    = {T, F, F}
       operator[]  = {^, |}
Output: 2
The given expression is "T ^ F | F", it evaluates true
in two ways "( (T ^ F) | F )" and "( T ^ (F | F) )". 

Input: symbol[]    = {T, T, F, T}
       operator[]  = {|, &, ^}
Output: 4
The given expression is "T | T & F ^ T", it evaluates true
in 4 ways ((T|T)&(F^T)), (T|(T&(F^T))), (((T|T)&F)^T) 
and (T|((T&F)^T)). 


Counting Boolean Parenthesizations
 

Solution:
Let T(i, j) represents the number of ways to parenthesize the symbols between i and j (both inclusive) such that the subexpression between i and j evaluates to true.

Let F(i, j) represents the number of ways to parenthesize the symbols between i and j (both inclusive) such that the subexpression between i and j evaluates to false.

Base Cases:

T(i, i) = 1 if symbol[i] = 'T' 
T(i, i) = 0 if symbol[i] = 'F' 
F(i, i) = 1 if symbol[i] = 'F' 
F(i, i) = 0 if symbol[i] = 'T' 

 

The cost is :
checking subwords of size 1 + checking subwords of size 2 + ... + checking subwords of size N
= N + N-1 + 2*(N-2) + 2*(N-2) + .. + (N-1)*(1)
= O(N^3)
Auxiliary Space: O(n2)

public int countBoolParenth(char[] symbols, char[] operators) {
	int n = symbols.length;
	int[][] T = new int[n][n];
	int[][] F = new int[n][n];

	for (int i = 0; i < n; i++) {
		T[i][i] = symbols[i] == 'T' ? 1 : 0;
		F[i][i] = symbols[i] == 'F' ? 1 : 0;
	}

	for (int w = 2; w <= n; w++) { // w: the width of the sliding window, [2, n]
		for (int i = 0, j = w-1; j < n; i++, j++) { // i..j: the sliding window, [i, j]
			for (int k = i; k < j; k++) { // k: the index of operator to be inserted into symbols
				// Store Total[i][k] and Total[k+1][j]
				int tik = T[i][k] + F[i][k];
				int tkj = T[k + 1][j] + F[k + 1][j];

				// Follow the recursive formulas according to the current operator
				if (operators[k] == '&') {
					T[i][j] += T[i][k] * T[k + 1][j];
					F[i][j] += (tik * tkj - T[i][k] * T[k + 1][j]);
				}

				if (operators[k] == '|') {
					F[i][j] += F[i][k] * F[k + 1][j];
					T[i][j] += (tik * tkj - F[i][k] * F[k + 1][j]);
				}

				if (operators[k] == '^') {
					T[i][j] += F[i][k] * T[k + 1][j] + T[i][k] * F[k + 1][j];
					F[i][j] += T[i][k] * T[k + 1][j] + F[i][k] * F[k + 1][j];
				}
			}
		}
	}
	return T[0][n - 1];
}

 

References:

http://www.geeksforgeeks.org/dynamic-programming-set-37-boolean-parenthesization-problem/

http://people.cs.clemson.edu/~bcdean/dp_practice/dp_9.swf

http://ineptprogrammer.blogspot.com/2014/11/counting-boolean-parenthesizations-you.html

http://courses.csail.mit.edu/6.006/fall10/handouts/dpproblems-sol.pdf

你可能感兴趣的:(boolean)