我目前正试图弄清楚如何检查布尔表达式!b && (c || !d)
和!(b || !c && d
的所有可能性,对布尔b
c
有八种可能的分配, d
我需要确定哪个组合会产生(!b && (c || !d)) != (!(b || !c && d)
我当前的代码是:
public static void Main(String[] args)
{
java.util.Random randy = new java.util.Random();
boolean expression1 = false;
boolean expression2 = false;
boolean[] b = {true, false};
boolean[] c = {true, false};
boolean[] d = {true, false};
int B = 0;
int C = 0;
int D = 0;
while(expression1 == expression2)
{
B = randy.nextInt(2);
C = randy.nextInt(2);
D = randy.nextInt(2);
expression1 = !b[B] && (c[C] || !d[D]);
expression2 = !(b[B] || !c[C] && d[D]);
}
if(expression1 != expression2)
{
JOptionPane.showMessageDialog(null, "b: " + b + "c: " + c + "d: " + d);
}
}
然而它似乎没有做到这一点。所以我的问题是我如何能够找出布尔表达式的所有可能性,然后将它们相互比较以查看它们是否彼此不相等。
答案 0 :(得分:2)
只有八种可能性,因此将它们全部枚举起来并不难。有点像这样(没有经过远程测试):
static boolean toBoolean(int n) {
if(n==0) {return false; }
return true;
}
...
for(int b_int=0; b_int<2; b_int++) {
for(int c_int=0; c_int<2; c_int++) {
for(int d_int=0; d_int<2; d_int++) {
boolean b = toBoolean(b_int);
boolean c = toBoolean(c_int);
boolean d = toBoolean(d_int);
boolean expr1 = whatever;
boolean expr2 = whatever else;
if(expr1 != expr2) {
// Eureka! signal success
}
}
}
}
只要你强行解决问题,就要考虑枚举而不是随机测试,特别是如果问题的可能性很小。也就是说,您可以尝试在表达式上使用de Morgan's laws。如果我自己做得对,你会找到一些有趣的东西。
答案 1 :(得分:2)
两个表达式都是相同的,因此它们将始终彼此相等。让我们对第二个表达式进行一些转换:
!(b || !c && d) # original expression
!(b || (!c && d)) # && has precedence over ||
!b && !(!c && d) # negate the whole expression
!b && (c || !d) # negate the right most expression
我们刚刚获得与第一个相同的表达式,因此(!b && (c || !d)) != (!(b || !c && d))
将始终评估为false。
答案 2 :(得分:2)
您当前的方法存在的问题是,您正在使用随机化来获取所有变量的所有组合,但这并不能保证您将获得所有变量。
另一个问题似乎在于你的代码片段的逻辑:如果在任何时候expression1 != expression2
你将离开while循环并且if语句将为true,它将打印消息对话框然后程序将退出。由于你使用的是random,每次使用不同的值时都会获得相同的值,但是你总会获得一种可能性。
一种方法是创建一个真值表,其中包含所涉及变量的真实性的所有组合,并且每次都测试您的表达式。例如:
private static void compareExpressions() {
final int NUMBER_OF_VARIABLES = 3;
final int NUMBER_OF_ROWS = (int) Math.pow(2, NUMBER_OF_VARIABLES);
boolean values[] = new boolean[NUMBER_OF_VARIABLES];
boolean expression1, expression2;
// Build a truth table
for(int i = 0; i < NUMBER_OF_ROWS; i++) {
for(int j = NUMBER_OF_VARIABLES - 1, k = 0; j >= 0; j--, k++) {
values[k] = (i / (int) Math.pow(2, j)) % 2 == 0 ? false : true;
}
// Compare what you need and show results for each row in the truth table
expression1 = !values[0] && (values[1] || !values[2]);
expression2 = !(values[0] || !values[1] && values[2]);
if(expression1 != expression2) {
System.out.println("b: " + values[0] + " c: " + values[1] + " d: " + values[2]);
}
}
}
使用这种方法可以创建任意大小的真值表但由于values[]
数组中的“未命名”变量或者如果有变量,变量数量会增加,因此会变得繁琐且容易出错不同的表达。
不幸的是,解决这个问题需要表达式的解析器以及存储变量的更好方法(例如,Map<String, Boolean>
)。
答案 3 :(得分:0)
您可以使用嵌套循环检查所有可能的组合。
for(int i=0;i<2;i++){
for(int j=0;j<2;j++){
for(int k=0;k<2;k++){
//Check b[i] c[j] d[k] for your condition and handle accordingly
}
}
}