简化Java IF或CASE语句

时间:2014-02-19 21:43:30

标签: java performance algorithm

我有一个包含四个字段的XML文件

<field1>
<field2>
<field3>
<field4>

这些字段的值可以是TRUE或FALSE。我想确定输出是A,B,C还是D.要做到这一点,我必须看看这四个字段,每个组合意味着输出是A,B,C或D.可能的组合和输出如下所述:

1T, 2F, 3F, 4F; A
1T, 2T, 3F, 4F; B
1T, 2T, 3T, 4F; C
1T, 2T, 3T, 4T; C
1T, 2F, 3T, 4F; A
1T, 2F, 3T, 4T; A
1T, 2F, 3F, 4T; A
1T, 2T, 3F, 4T; B

数字表示字段编号,数字后面的字符表示值是TRUE还是false,例如,第一个组合(-1T, 2F, 3F, 4F; A)表示如果field1为TRUE,field2为false,field3为false则输出是A. 如果没有匹配,则输出为D.

显然我可以做类似

的事情
if(field1, !field2, !field3, !field4)
 return 'A'
else if(field1, field2, !field3, !field4)
 return 'B'
else if(field1, field2, field3, !field4)
 return 'C'
...
....
....
and so on

需要注意的是,其中一些字段可能为空(即标记可能不存在)。如果没有100个IF语句,是否有更简单的方法来编码这些组合?

提前致谢

10 个答案:

答案 0 :(得分:4)

有一个名为Karnaugh map的工具,专门用于简化这种逻辑。

自从我不得不触摸它以来已经过了五年了,但是如果你搜索它,就会有很多关于这个主题的信息。


如果你想要有创意,这不是唯一的方法。

您可以将字段汇总为单个值并使用地图(Actual map syntax here

myMap["TFTF"] = 'A'

如果你更多地考虑问题,我相信你可以找到其他创造性的方法

答案 1 :(得分:2)

您可以将某些值编码为某个数字,这样每个组合都会给出一个未给出任何其他组合的数字。

该编码可能只是二进制。

1000=8  A
1100=12 B
1110=14 C
1111=16 C
1010=10 A
1011=11 A
1001=9  A
1101=13 B

然后你需要一个像地图这样的数据结构来将每个数字与输出相关联。

编辑:我说了一个数字,但实际上任何编码都可以正常工作,因为地图几乎可以作为关键字。其他编码:"TFFF", "1000", "1T 2F 3F 4F", Arrays.asList(true, false, false, false) ...

答案 2 :(得分:2)

根据表的“密集”程度,您可能只想将字段视为二进制数字,构造相应的数字然后进行数组查找:

  234
0 000: A
1 001: A
2 010: A
3 011: A
4 100: B
5 101: B
6 110: C
7 111: C

int x = (field2 ? 4 : 0) + (field3 ? 2 : 0) + (field4 ? 1 : 0)
return "AAAABBCC".charAt(x);

例如,这只会工作btw(field4和1与输出无关):

return field2 ? (field3 ? 'C' : 'B') : 'A'

答案 3 :(得分:1)

我会去做这样的事情,如下(伪代码):

int c=0;
array r[4]= [field1, field2, field3, field4];

for(int i=0; i<4; i++) { 

    if (!r[i]) break;

    c++;
}

return 'A'+c;

根据你想要处理null的方式,如果(r [i]为null)你可以愚蠢地添加一个测试{}

答案 4 :(得分:1)

您可以使用查找表简化操作:

table[1][0][0][0] = 'A'
table[1][1][0][0] = 'B'
table[1][1][1][0] = 'C'
table[1][1][1][1] = 'C'
table[1][0][1][0] = 'A'
table[1][0][1][1] = 'A'
table[1][0][0][1] = 'A'
table[1][1][0][1] = 'B'

创建一个函数将字段变为1或0然后将其插入表中并获得答案。

答案 5 :(得分:1)

根据模式的外观,如果我们只是使用该数据集,我们可以通过执行以下操作来测试它:

if (field3 && field2) 
    return 'C';
else if (!field3 && field2) 
    return 'B';
else 
    return 'A';

答案 6 :(得分:1)

好的,首先你需要安全地处理空值。您可以为此目的编写两种方法:

boolean safeTrue(Boolean b){
    return b != null && b.booleanValue();
}

boolean safeFalse(Boolean b){
    return b != null && !(b.booleanValue());
}

之后,你可以通过使用卡诺图来减少你的布尔表达式,正如其他一些研究员所建议的那样。结果将是:

if(safeTrue(field1) && safeFalse(field2)){
    return 'A';
}
if(safeTrue(field1) && safeTrue(field2) && safeFalse(field3)){
    return 'B';
}
if(safeTrue(field1) && safeTrue(field2) && safeTrue(field3)){
    return 'C';
}
//finally, return some value for the case when no combiantion has been matched.

答案 7 :(得分:1)

如果你以这种方式阅读它并代表二进制它是:

1T, 2F, 3F, 4F; A 1000 (8)
1T, 2F, 3F, 4T; A 1001 (9)
1T, 2F, 3T, 4F; A 1010 (10)
1T, 2F, 3T, 4T; A 1011 (11)
1T, 2T, 3F, 4F; B 1100 (12)
1T, 2T, 3F, 4T; B 1101 (13)
1T, 2T, 3T, 4F; C 1110 (14)
1T, 2T, 3T, 4T; C 1111 (15)

所以:

if binaryRepr>=8 && binaryRepr<=11 then A
if binaryRepr>=12 && bicnaryRepr<=13 then B
if binaryRepr>=14 then C
else D

答案 8 :(得分:1)

根据输入和输出列表,您只需field2field3。然后,我建议如下:

if (!field2)
   return 'A';
else if (field3)
   return 'C';
else 
   return 'B';

使用此解决方案,您应该在null之前处理可能的if值。

答案 9 :(得分:1)

鉴于您列出的案例,第一个和第四个字段无关紧要,您只需要:

char foo(boolean field2, boolean field3)
{
    return field2 ? (field3 ? 'C' : 'B') : 'A';
}