这里有一些快速的解决方案。
构造数组
public static final long[] toThreeBitCombinations(long e) {
// get lowest 1 bit; turn off that bit;
final long a = e & -e; e ^= a;
final long b = e & -e; e ^= b;
final long c = e & -e; e ^= c;
final long d = e & -e; e ^= d;
final long ab = a | b;
final long ae = a | e;
final long be = b | e;
final long cd = c | d;
return new long[] { cd | e, be | d, ae | d, be | c, ae | c,
ab | e, b | cd, a | cd, ab | d, ab | c
};
}
此方法产生的输出与您对示例输入的期望相同。如果您希望数组按升序排列:
public static final long[] toThreeBitCombinations(long e) {
// get lowest 1 bit; turn off that bit;
final long a = e & -e; e ^= a;
final long b = e & -e; e ^= b;
final long c = e & -e; e ^= c;
final long d = e & -e; e ^= d;
final long ab = a | b;
final long ae = a | e;
final long be = b | e;
final long cd = c | d;
return new long[] { ab | c, ab | d, a | cd, b | cd, ab | e,
ae | c, be | c, ae | d, be | d, cd | e
};
}
可以看出,顺序颠倒了。
对于整个数组的构造,我们有:
ALU 使用情况
可变内存使用
方法调用
26 条 ALU 指令、80 字节使用和 1 个方法调用整个数组与此处介绍的其他解决方案相比具有优势。它也不需要额外的工作来确定开始这些循环的三位组合值。
无需构造数组即可判断元素是否在数组中
这通常比构造一个十元素数组并在其上使用线性搜索要慢,除非您在构造数组后很快就将其丢弃。
public static final boolean inThreeBitCombinations(final long three, final long five) {
return ((three & ~five) == 0) && (Long.bitCount(three) == 3);
}