简体   繁体   English

Java中的整数用于哪个位

[英]Which bit is on for an integer in Java

I have written this code to check which bits are on of an Integer (if represented in binary) in Java: 我编写了这段代码来检查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;
}

The above written code works fine. 上面编写的代码工作正常。 But it has a loop which runs 32 times (In Java integer is 32 bit long). 但是它有一个运行32次的循环(在Java整数中是32位长)。 I want to minimize this complexity. 我想尽量减少这种复杂性。 Please share the better solution. 请分享更好的解决方案。 Thanks in advance. 提前致谢。

You could use a bit mask to try to reduce the times through the loop. 您可以使用位掩码来尝试减少循环的时间。 You add a few operations but potentially do half the looping: 您添加了一些操作,但可能会执行一半的循环:

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;
}

This potentially would increase time depending on the data coming in. 这可能会增加时间,具体取决于进入的数据。

You can also reduce looping in half by doing two bits at a time: 您还可以通过一次执行两个位来减少一半的循环:

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;
}

The complexity is O(1), so there's not much to "minimize" there. 复杂性是O(1),因此在那里“最小化”并不多。

Your code is okay.. here it is refactored slightly. 你的代码还可以..这里稍微重构一下。

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;
}

Btw, have you considered using a BitSet ? 顺便说一下,你考虑过使用BitSet吗?

32 loops sounds good for this application. 32个循环听起来不错。 You can use a StringBuffer instead of List if you want to collect the digits faster. 如果要更快地收集数字,可以使用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();
}

Improving O(1) code seems trivial but this code is a slight improvement: 改进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;

Rather then making all 32 bit comparisons, this code will end as soon as the last bit has been counted. 而不是进行所有32位比较,此代码将在最后一位计数后立即结束。 It is much more efficient for integers that are sparsely populated with 1 s and no less efficient for integers which are highly populated. 这是对于那些人口稀少整数更有效的1秒和没有对这些人口稠密的整数效率较低。

Since you know the exact length of the integer I would recommend using a bool[] instead. 既然你知道整数的确切长度,我建议使用bool[]代替。 There is not much you can do about the complexity though. 尽管如此,你对复杂性无能为力。 It is as fast as it can get and the JIT is probably going to unroll the loop of this code anyways. 它的速度和它一样快,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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM