在Java中添加2个BitSet

时间:2012-07-29 04:10:21

标签: java bit-manipulation bitwise-operators bits

嗯,我需要在java中添加两个BitSet。 我尝试使用XOR(总和)和AND(进位)的基本操作添加.. 考虑进位 ..

但答案是完全正确的...... 这就是我尝试过的..

public static BitStorage Add(int n, BitStorage ...manyBitSets)
{
    BitStorage sum = new BitStorage(0, n);      //discarding carry out of MSB
    System.out.print("Addition of: ");
    for(BitStorage bitStorage:manyBitSets)
    {
        //System.out.print(sum+"\t");
        //System.out.print(bitStorage+"\t");
        System.out.println("~~~~~");
        for(int i=n-1;i>=0;i--)
        {
            if(i==n-1)
            {
                System.out.println(sum + " + " +bitStorage);
                sum.set(i, sum.get(i)^bitStorage.get(i));
                //System.out.println(sum.get(i)+" XOR "+bitStorage.get(i));
            }
            else
            {
                System.out.println(sum + " + " +bitStorage+"\t"+(sum.get(i)?"1":"0"+"^"+(bitStorage.get(i)?"1":"0")+"^"+(sum.get(i+1)?"1":"0"+"&"+(bitStorage.get(i+1)?"1":"0"))));
                sum.set(i, sum.get(i)^bitStorage.get(i)^(sum.get(i+1)&bitStorage.get(i+1)));      //carry taken here
                //System.out.println(sum.get(i)+" XOR "+bitStorage.get(i)+" XOR ("+bitStorage.get(i+1)+" AND "+sum.get(i+1));
            }
        }
    }   
    return sum;
}

PS:BitStorage类只不过是BitSet的自身实现,还有一些额外的方法..比如Add,Subtract,Shift等

它有2个成员:

  1. 作为最大大小的整数(n)(我不希望向量增长或收缩以影响按位运算=>因此所有操作都在n时完成) - >例如:n为4,然后位在BitSet中占据位置o到3
  2. 传入构造函数
  3. 的大小为n的BitSet对象

    另外2点:

    • 我想把它转换成长数组或字节数组然后添加,但我只需要JDK 6中的解决方案而不是7
    • 我不需要从MSB生成的进位,我想要的答案是相同的no(位),即
    抱歉很多次使用“我想......”..有点累。很多东西! 嗯,我需要这个算法的一部分.. 期待回复.. :) :))

3 个答案:

答案 0 :(得分:2)

我很累,所以请原谅我,如果这很难看。即使不应该设置任何东西,你的携带方法也会被完全打破并设置错误的位。你应该计算好进行,因此,没有理由特殊情况下最后一点,进位将会消失。通过实际将最后一个结果传递到下一个循环迭代中,逻辑就更简单了。

public static BitStorage Add(int n, BitStorage ...manyBitSets)
{
    BitStorage sum = new BitStorage(0, n);      //discarding carry out of MSB
    System.out.print("Addition of: ");
    for(BitStorage bitStorage:manyBitSets)
    {
        boolean carry = false;
        boolean lastcarry = false;
        //System.out.print(sum+"\t");
        //System.out.print(bitStorage+"\t");
        System.out.println("~~~~~");
        for(int i=0;i<n;i++)
        {
                System.out.println(sum + " + " +bitStorage+"\t"+(sum.get(i)?"1":"0"+"^"+(bitStorage.get(i)?"1":"0")+"^"+(sum.get(i+1)?"1":"0"+"&"+(bitStorage.get(i+1)?"1":"0"))));
                lastcarry = carry;
                carry = sum.get(i) && bitStorage.get(i);
                sum.set(i, lastcarry^sum.get(i)^bitStorage.get(i));      //carry taken here
                //System.out.println(sum.get(i)+" XOR "+bitStorage.get(i)+" XOR ("+bitStorage.get(i+1)+" AND "+sum.get(i+1));
        }
    }   
    return sum;
}

我为变量使用了boolean,因为我将该类构建为BitSet上的瘦包装器,如果你使用int或者不是更改它们。

答案 1 :(得分:1)

这是一个有趣的问题,让我猜了一会......

我无法首先推导出逻辑,但后来又切换回基础并派生boolean expression计算总和&amp;进行3位操作,这是解决方案:

public static BitSet addBitSet(int n, List<BitSet> bitSetList){
    BitSet sumBitSet = new BitSet(n);
    for (BitSet firstBitSet : bitSetList) {
        BitSet secondBitSet = (BitSet) sumBitSet.clone();
        System.out.println("A:  " + printBitSet(firstBitSet, 6));
        System.out.println("B:  " + printBitSet(secondBitSet, 6));
        boolean carryForNext = false, sum,a,b,c;
        for (int i = n - 1; i >= 0; i--) {
            a=firstBitSet.get(i);
            b=secondBitSet.get(i);
            c=carryForNext;
            sum = a&!b&!c|!a&!b&c|!a&b&!c|a&b&c;
            carryForNext = a&b&!c|a&!b&c|!a&b&c|a&b&c;
            sumBitSet.set(i,sum);
        }
        System.out.println("SUM:" + printBitSet(sumBitSet, 6));
    }
    System.out.println(printBitSet(sumBitSet, 6));
    return sumBitSet;
}

以下是printBitSet的代码:

public static String printBitSet(BitSet bitSet, int size) {
    StringBuilder builder = new StringBuilder("");
    for (int i = 0; i < size; i++) {
        if (bitSet.get(i))
            builder.append("1");
        else
            builder.append("0");
    }
    return builder.toString();
}

答案 2 :(得分:0)

我想出了这个bug ..这是携带的问题.. 而是使用相同的逻辑..我决定了另一个逻辑.. 只是对两个数字进行异或(得到总和)..并再次将其作为一个数字加入到一个带有进位的数字中(从AND原始数字得到)。 AND输出(进位)在每次迭代中向左移位..因为LSB端位添加没有任何进位添加

当进位位集全为0(假)时,我们停止循环

一个例子:

  1. 0001
  2. 0011
  3. = 0010 - &gt;(XOR = sum)
  4. +0010 - &gt;(AND输出=在左移后显示进位..现在它将被添加到XOR输出中)
  5. = 0000 - &gt;(XOR =总和)
  6. +0100 - &gt;(AND输出=在左移后显示进位..现在它将被添加到XOR输出中)
  7. = 0100 - &gt;(XOR =总和.. 最终答案
  8. 0000 - &gt;(AND输出=携带..左移后显示..我们停在这里.. 停止,因为所有都是0)))
  9. 样本:)

    import java.util.*;
    public class BitSetAddition
    {
    static String nums[] = {"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};
    public static void main(String args[])
    {
        for(int q=0;q<nums.length;q++)
        {
            System.out.print(q+1+" -> ");
            BitSet b1 = new BitSet();
            String s = nums[q];
            b1.set(0, s.charAt(0)=='1'?true:false);
            b1.set(1, s.charAt(1)=='1'?true:false);
            b1.set(2, s.charAt(2)=='1'?true:false);
            b1.set(3, s.charAt(3)=='1'?true:false);
    
            for(int i=0;i<4;i++)
                System.out.print(b1.get(i)?"1":"0");
                System.out.print(" + ");
    
            BitSet b2 = new BitSet();
            String a = "0001";
            b2.set(0, a.charAt(0)=='1'?true:false);
            b2.set(1, a.charAt(1)=='1'?true:false);
            b2.set(2, a.charAt(2)=='1'?true:false);
            b2.set(3, a.charAt(3)=='1'?true:false);
    
            for(int i=0;i<4;i++)
                System.out.print(b2.get(i)?"1":"0");
                System.out.print(" = ");
    
            BitSet sum = new BitSet();
            BitSet carry = new BitSet();
            BitSet toAdd = new BitSet();
            BitSet tempSum = new BitSet();
            BitSet tempCarry = new BitSet();
    
            sum = b1;
            toAdd = b2;
            do
            {
                copy(4, tempSum, sum);
                copy(4, tempCarry, toAdd);
                tempSum.xor(toAdd);
                tempCarry.and(sum);
                copy(4, sum, tempSum);
                copy(4, carry, leftShift(4, tempCarry));
                copy(4, toAdd, carry);
                //sum.set(i, b1.get(i)^b2.get(i)^(b1.get(i+1)&b2.get(i+1)));
            }while(!carry.equals(new BitSet()));
                //if(i+2<=3)
                    //sum.set(i, b1.get(i)^b2.get(i)^(b1.get(i+1)&b2.get(i+1)&(b1.get(i+2)&(b2.get(i+2)))));
                //else if(i+1<=3)
                    //sum.set(i, b1.get(i)^b2.get(i)^(b1.get(i+1)&b2.get(i+1)));
                //else
                    //sum.set(i, b1.get(i)^b2.get(i));
            for(int i=0;i<4;i++)
                System.out.print(sum.get(i)?"1":"0");
    
            System.out.println();
        }
    }
    static void copy(int n,BitSet b, BitSet toCopy)
    {
        for(int i=0;i<n;i++)
            b.set(i, toCopy.get(i));
    }
    static BitSet leftShift(int n, BitSet b)
    {
        for(int i=0;i<n;i++)
            b.set(i, b.get(i+1));
            b.set(n-1, false);
            return b;
    }
    }
    

    程序中的注释属于我之前的逻辑..我发现我之前的逻辑更复杂:P ..如果你想要忽略程序的注释:)

    注意:我不想要MSB位添加的进位...根据算法(我需要这个)...所以答案(总和)具有相同的位数...任何人都可以调整,如果他们想要:)