Algorithm 计数布尔括号的实现
给定一个包含符号{true,false,and,or,xor}的布尔表达式,计算将表达式括起来以使其计算结果为true的方法的数量 例如,只有一种方法可以将“true和false xor true”括起来,使其计算结果为true 这是我的算法Algorithm 计数布尔括号的实现,algorithm,implementation,dynamic-programming,Algorithm,Implementation,Dynamic Programming,给定一个包含符号{true,false,and,or,xor}的布尔表达式,计算将表达式括起来以使其计算结果为true的方法的数量 例如,只有一种方法可以将“true和false xor true”括起来,使其计算结果为true 这是我的算法 we can calculate the total number of parenthesization of a string Definition: N - the total number of True - the number of p
we can calculate the total number of parenthesization of a string
Definition:
N - the total number of
True - the number of parenthesizations that evaluates to true
False - the number of parenthesizations that evaluates to false
True + False = N
Left_True - the number of parenthesization in the left part that evaluates to True
same to Left_False, Right_True, Right_False
we iterate the input string from left to right and deal with each operator as follows:
if it is "and", the number of parenthesization leads to true is
Left_True * Right_True;
if it is "xor", the number of parenthesization leads to true
Left_True * Right_False + Left_False * Right_True
if it is 'or', the number is
N - Left_False * Right_False
Here is my psuedocode
n = number of operator within the String
int[n][n] M; // save number of ways evaluate to true
for l = 2 to n
for i = 1 to n-l+1
do j = i+l-1
// here we have different string varying from 2 to n starting from i and ending at j
for k = i to j-1
// (i,k-1) is left part
// (k+1, j) is right part
switch(k){
case 'and': // calculate, update array m
case 'or': // same
case 'xor':
}
we save all the solutions to subproblems and read them when we meet them again. thus save time.
我们能有更好的解决方案吗 您的伪代码给出了一个O(2^n)格式的算法。我想你可以在O(n^3)中找到一些东西。
首先,让我们看看算法的复杂性。假设检查括号所需的操作数是
T(n)
。如果我理解得很好,您的算法包括:
- 将表达式分成两部分(n-1种可能性)
- 检查左右部分是否有适当的括号
T(n)
=检查你是否在第一个位置切割
+检查你是否在第二个位置切割
+…+<代码>检查是否在最后一个位置切割
T(n)
=T(1)+T(n-1)
+T(2)+T(n-2)
+…+<代码>T(n-1)+T(1)+n
稍微计算一下就会知道T(n)=2^n*T(1)+O(n^2)=O(2^n)
我的想法是,你只需要检查括号中是否有“子词”。“子词_i_j”由位置i和位置j之间的所有字母组成。当然
i这个问题可以用动态算法来解决,它类似于矩阵链乘法问题,具体答案如下:
1、 让运算由操作数a_i和运算符b_j(1这里是计算布尔和运算符数组括号的代码
时间复杂度O(N^3)和空间复杂度O(N^2)
publicstaticint-countingbooleanConstrations(bool[]布尔值,string[]运算符)
{
int[,]trueTable=新的int[boolValues.Length,boolValues.Length];
int[,]false table=新的int[boolValues.Length,boolValues.Length];
for(int j=0;j=0;i--)
{
如果(i==j)
{
trueTable[i,j]=布尔值[i]?1:0;
假值[i,j]=布尔值[i]?0:1;
}
其他的
{
int-trueSum=0;
int-falseSum=0;
对于(int k=i;k
你说的“我们能有一个更好的解决方案吗?”是什么意思?假设你要求一个:请定义“更好”。你是否在寻找一个更快的解决方案,一个使用更少代码、更少内存使用的解决方案……此外,你可能想进一步澄清你的伪代码,我这一次很难弄清楚它到底应该如何工作(如果您在交换机中编写所需内容,可能会有所帮助。我正在寻找更快的解决方案和更少的代码实现。例如,计算括号的方式很繁琐,括号导致true和false我很困惑–(true和false)xor true
和true和(false xor true)
两者的计算结果均为true。@ben同样,如果运算顺序是从左到右,那么“true and false xor true”也是一个解决方案。我也很困惑:如果是“or”,则数字是N-left\u false*right\u false
。我感觉,除了N之外,还有更多的括号
public static int CountingBooleanParenthesizations(bool[] boolValues, string[] operators)
{
int[,] trueTable = new int[boolValues.Length, boolValues.Length];
int[,] falseTable = new int[boolValues.Length, boolValues.Length];
for (int j = 0; j < boolValues.Length; j++)
{
for (int i = j; i >= 0; i--)
{
if (i == j)
{
trueTable[i, j] = boolValues[i] ? 1 : 0;
falseTable[i, j] = boolValues[i] ? 0 : 1;
}
else
{
int trueSum = 0;
int falseSum = 0;
for (int k = i; k < j; k++)
{
int total1 = trueTable[i, k] + falseTable[i, k];
int total2 = trueTable[k + 1, j] + falseTable[k + 1, j];
switch (operators[k])
{
case "or":
{
int or = falseTable[i, k] * falseTable[k + 1, j];
falseSum += or;
or = total1 * total2 - or;
trueSum += or;
}
break;
case "and":
{
int and = trueTable[i, k] * trueTable[k + 1, j];
trueSum += and;
and = total1 * total2 - and;
falseSum += and;
}
break;
case "xor":
{
int xor = trueTable[i, k] * falseTable[k + 1, j] + falseTable[i, k] * trueTable[k + 1, j];
trueSum += xor;
xor = total1 * total2 - xor;
falseSum += xor;
}
break;
}
}
trueTable[i, j] = trueSum;
falseTable[i, j] = falseSum;
}
}
}
return trueTable[0, boolValues.Length - 1];
}