我编写了这段代码来检查Java中Integer(如果用二进制表示)的哪些位是打开的:
public static List<String> list(int val)
{
List<String> dummyList = new ArrayList<String>();
int bit = 1;
int x;
for(int i=0; i<32; i++)
{
x = bit;
if((x&val)!=0)
dummyList.add(String.valueOf(i+1));
bit = bit << 1;
}
return dummyList;
}
以上编写的代码工作正常。但是它有一个运行32次的循环(在Java整数中是32位长)。我想尽量减少这种复杂性。请分享更好的解决方案。提前谢谢。
答案 0 :(得分:1)
您可以使用位掩码来尝试减少循环次数。您添加了一些操作,但可能会执行一半的循环:
public static List<String> list(int val) {
List<String> dummyList = new ArrayList<String>();
int loop = 32;
// Mask the 16 MSB if all are zero only loop on the 16 LSB
if((val & 0xFFFF0000) == 0){
loop = 16;
}
int bit = 1;
int x;
for (int i = 0; i < loop; i++) {
x = bit;
if ((x & val) != 0) {
dummyList.add(String.valueOf(i + 1));
}
bit <<= 1;
}
return dummyList;
}
这可能会增加时间,具体取决于进来的数据。
您也可以通过一次做两位来减少一半的循环:
public static List<String> list(int val) {
List<String> dummyList = new ArrayList<String>();
int bit = 3;
int x;
for (int i = 0; i < 32; i += 2) {
x = (bit & val);
switch (x) {
case 1:
dummyList.add(String.valueOf(i + 1));
break;
case 2:
dummyList.add(String.valueOf(i+2));
break;
case 3:
dummyList.add(String.valueOf(i+1));
dummyList.add(String.valueOf(i+2));
break;
default:
}
val >>= 2;
}
return dummyList;
}
答案 1 :(得分:0)
复杂度为O(1),因此没有太多“最小化”。
你的代码没问题......这里稍微重构一下。
public static List<String> list(int val) {
List<String> dummyList = new ArrayList<String>();
for (int i = 0; i < 32; i++)
if ((1 << i & val) != 0)
dummyList.add("" + (i+1));
return dummyList;
}
顺便问一下,您考虑过使用BitSet
吗?
答案 2 :(得分:0)
32个循环听起来很适合这个应用程序。如果要更快地收集数字,可以使用StringBuffer而不是List。
public static String list(int val)
{
StringBuffer dummyList = new StringBuffer();
int bit = 1;
int x;
for(int i=0; i<32; i++)
{
x = bit;
dummyList.append((x&val) ? '1' : '0' );
bit = bit << 1;
}
return dummyList.toString();
}
答案 3 :(得分:0)
改进O(1)
代码似乎微不足道,但这段代码略有改进:
public static List<String> list(int val) {
List<String> dummyList = new ArrayList<String>();
for (int i=0; val!=0 && i<32; ++i){
if ((1 << i & val) != 0) {
dummyList.add("" + (i+1));
val &= val -1; // unset the last set bit (current bit)
} // causes loop to end early when all bits are counted
}
return dummyList;
而不是进行所有32位比较,此代码将在最后一位计数后立即结束。对于使用1
稀疏填充的整数来说效率要高得多,对于人口密集的整数来说效率也不低。
答案 4 :(得分:0)
由于您知道整数的确切长度,我建议您改用bool[]
。尽管如此,你对复杂性无能为力。它的速度和它一样快,JIT可能会打开这段代码的循环。
public static bool[] list(int val)
{
bool[] a = new bool[32];
for(int i=0; i<32; i++)
{
a[i] = ((1 << i) & val) != 0;
}
return a;
}