繁体   English   中英

Java中的整数用于哪个位

[英]Which bit is on for an integer 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;
}

上面编写的代码工作正常。 但是它有一个运行32次的循环(在Java整数中是32位长)。 我想尽量减少这种复杂性。 请分享更好的解决方案。 提前致谢。

您可以使用位掩码来尝试减少循环的时间。 您添加了一些操作,但可能会执行一半的循环:

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

复杂性是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吗?

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

改进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秒和没有对这些人口稠密的整数效率较低。

既然你知道整数的确切长度,我建议使用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;
}

暂无
暂无

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

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