Java 位集示例

Posted

技术标签:

【中文标题】Java 位集示例【英文标题】:Java BitSet Example 【发布时间】:2012-03-09 04:09:41 【问题描述】:

我正在寻找一个很好的 Java BitSet 示例来处理 0 和 1。我尝试查看 Javadocs,但仅阅读该类就无法理解该类的用法。例如,andorxor 方法如何作用于两个不同的 BitSet 对象?

例如:

  BitSet bits1 = new BitSet();
  BitSet bits2 = new BitSet();

  bits2.set(1000001);
  bits1.set(1111111);

  bits2.and(bits1);

  System.out.println(bits2);

如果我这样做,它会返回 bits2 为空,为什么会这样?

【问题讨论】:

en.wikipedia.org/wiki/Bitwise_operation - 它们的工作方式与将& | ^ 等与原始数字类型一起使用时完全相同。 什么,具体来说,你不明白吗?您创建一个 BitSet,然后在其上调用函数,例如 .and.or.xor。这些函数中的每一个都将另一个 BitSet 对象作为参数。 好吧,我试着在上面的例子中做一个and 并且bitset 变成了空的。 @SteffanHarris 请查看我的更新答案 【参考方案1】:

这里有一些关于 bitSet 的链接可以帮助你:

http://www.java-samples.com/showtutorial.php?tutorialid=378 http://www.codeguru.com/java/tij/tij0090.shtml http://imagenious.wordpress.com/2008/02/05/java-bitset-vs-primitive/

更新:

在文档中是这样说的:

公共无效集(int bitIndex)

Sets the bit at the specified index to true.

所以当你调用bits2.set(10);时,它被认为是十进制数而不是1 0所以你得到的是下面的数字1000000000

为了正确设置,在本例中,我想将第 2 位设置为 1,因此我调用 bits2.set(1);,因为索引从 0 开始。

总结,对于每个设置为 1 的位,您需要调用 bitSet.Set 并为其提供位的索引。

【讨论】:

【参考方案2】:

对于您提到的具体问题:当您调用bits2.set(1000001) 时,您将百万分之一和第一位设置为true。然后当你与bits1 相交时,它设置了 100 万、111000 和 111 位,它们没有共同的位。

我认为你的意思

 bits2.set(0); // set the 0th bit
 bits2.set(6); // set the 6th bit

这有助于解决问题吗?

【讨论】:

“他们没有共同点”你怎么说这个?因为我看到 bits1 和 bits2 的第一个和最后一个位是共同的?仍然不明白为什么 bits2 变空了。能否请您再简单地解释一下。 @JAVA 我不知道如何更清楚地解释 bits1 只有一个位设置为 true,即索引一百万零一(数字 1,000,001)和 bits2只有一位设置为真,即索引 1111011111 (1,111,111) 处的位。【参考方案3】:

BitSet 没有方便的方法来接受这样的位字符串。我在下面提供了一些,现在该示例可以按您的预期工作。请注意,这使用了 Java 7 中的新功能;如果您想使用 Java 6,很容易在网上找到这些方法的实现。

import java.util.BitSet;

class Scratch 
    public static void main(String[] args) 
        BitSet bits1 = fromString("1000001");
        BitSet bits2 = fromString("1111111");

        System.out.println(toString(bits1)); // prints 1000001
        System.out.println(toString(bits2)); // prints 1111111

        bits2.and(bits1);

        System.out.println(toString(bits2)); // prints 1000001
    

    private static BitSet fromString(final String s) 
        return BitSet.valueOf(new long[]  Long.parseLong(s, 2) );
    

    private static String toString(BitSet bs) 
        return Long.toString(bs.toLongArray()[0], 2);
    

【讨论】:

完美!我喜欢你的toString(BitSet bs) 方法。很有用!您可以反转位以将 bit_0 放在右侧。 这是最好的答案,因为它理解 OP 的困惑(以及我的困惑!)并直接进入正题。【参考方案4】:

如果您想使用位,您可以在 Java 7 中使用 int 值。

int bits2 = 0b1000001;
int bits1 = 0b1111111;
bits2 &= bits1;
System.out.println(Integer.toBinaryString(bits2));

打印

1000001

【讨论】:

当您将它们保存为ints 时,它们是在使用4 byte 还是7 bits @daydreamer 查看source code 表明BitSet 在幕后实现为long[]。 “第 i 位存储在位 [i/64] 的位位置 i % 64 中(其中位位置 0 指的是最低有效位,而 63 指的是最高有效位)。”所以至少,任何 BitSet 都将使用 64 位。甚至参数化的构造函数也说“创建一个位集,其初始大小足够大以显式表示具有范围内索引的位......”【参考方案5】:

我正在分享我使用比特串作为输入来创建 BitSet 对象的实现。

private static BitSet createFromString(String s) 
    BitSet t = new BitSet(s.length());
    int lastBitIndex = s.length() - 1;

    for (int i = lastBitIndex; i >= 0; i--) 
        if ( s.charAt(i) == '1')
            t.set(lastBitIndex - i);                            
                       
    

    return t;

对于字符串输入“1001”

BitSet s1 = createFromString("1001");
    System.out.println(s1);

输出:

0, 3

【讨论】:

为什么要使用while循环? for 循环也可以,因为您在每次迭代中将 i 减一。 编辑:使用 For 循环的代码的更好版本,感谢@Clément 的建议 :)【参考方案6】:

试试这个:

import java.util.BitSet;

public class BitSetExample 

    public static void main(String args[])
        BitSet bits1 = new BitSet(7);
        BitSet bits2 = new BitSet(7);

        // set some bits
        for(int i = 0; i < 7; i++) 
            if((i % 2) == 0) bits1.set(i);
            if((i % 3) != 0) bits2.set(i);
        

        System.out.println("BitSet1: ");

        for(int i = 0; i < 7; i++) 
            System.out.print(bits1.get(i)? "1 ": "0 ");
        

        System.out.println("\nBitSet2: ");

        for(int i = 0; i < 7; i++) 
            System.out.print(bits2.get(i)? "1 ": "0 ");
        

        System.out.println();

        //And
        bits1.and(bits2);

        System.out.println("b1 = b1 AND b2\nBitSet1: ");

        for(int i = 0; i < 7; i++) 
            System.out.print(bits1.get(i)? "1 ": "0 ");
        

        System.out.println();
        System.out.println("BitSet2: ");

        for(int i = 0; i < 7; i++) 
            System.out.print(bits2.get(i)? "1 ": "0 ");
        

        System.out.println();

        //Or
        bits1.or(bits2);

        System.out.println("b1 = b1 OR b2\nBitSet1: ");

        for(int i = 0; i < 7; i++) 
            System.out.print(bits1.get(i)? "1 ": "0 ");
        

        System.out.println();
        System.out.println("BitSet2: ");

        for(int i = 0; i < 7; i++) 
            System.out.print(bits2.get(i)? "1 ": "0 ");
        

        System.out.println();

        //Xor
        bits1.xor(bits2);

        System.out.println("b1 = b1 XOR b2\nBitSet1: ");

        for(int i = 0; i < 7; i++) 
            System.out.print(bits1.get(i)? "1 ": "0 ");
        

        System.out.println();
        System.out.println("BitSet2: ");

        for(int i = 0; i < 7; i++) 
            System.out.print(bits2.get(i)? "1 ": "0 ");
        

        System.out.println();

        //Setting bits to zero and one
        bits1.set(1);
        bits2.set(1,false);

        System.out.println("set bit 1 of BitSet1 to one and set bit 1 of BitSet2 to zero\nBitSet1: ");

        for(int i = 0; i < 7; i++) 
            System.out.print(bits1.get(i)? "1 ": "0 ");
        

        System.out.println();
        System.out.println("BitSet2: ");

        for(int i = 0; i < 7; i++) 
            System.out.print(bits2.get(i)? "1 ": "0 ");
        

        System.out.println();

    

我希望这是有用的。欲了解更多信息,请访问:https://github.com/m-vahidalizadeh/foundations/blob/master/src/data_structures/BitSetExample.java。

【讨论】:

以上是关于Java 位集示例的主要内容,如果未能解决你的问题,请参考以下文章

Java BitSet(位集)

移动 Java 位集

如何在 C 中实现位集?

Cuda:XOR 单个位集与位集数组

比较位集的最快方法(位集上的 < 运算符)?

用不同大小的位集替换所有内部位集