Java 知道什么时候有';1和0等于一个字符串的数量

Java 知道什么时候有';1和0等于一个字符串的数量,java,bit-manipulation,bitwise-operators,Java,Bit Manipulation,Bitwise Operators,对使用逐位运算符计算位字符串中1=0的数量感兴趣。如果1s=0s,则输出。有没有关于使用Java来实现这一点的想法?多谢各位 public void function(int binaryNumber) { BigInteger val = new BigInteger(String.valueOf(binaryNumber)); val = val.abs(); int count = val.bitCount(); String binaryString =

对使用逐位运算符计算位字符串中1=0的数量感兴趣。如果1s=0s,则输出。有没有关于使用Java来实现这一点的想法?多谢各位

public void function(int binaryNumber) {
    BigInteger val = new BigInteger(String.valueOf(binaryNumber));
    val = val.abs();
    int count = val.bitCount();
    String binaryString = val.toString(2);

    System.out.println("count = " + count);
    System.out.println("bin = " + binaryString);
}
更新:将位格式显示为无符号,添加了
long
biginger
版本,并添加了忽略符号的版本

Integer
类有许多用于执行位魔术的
static
方法。如果输入是
int
,则无需使用
biginger
<如果需要,code>Long具有相同的方法

下面是一个进行您想要的测试的方法。它使用:

  • -返回指定的
    int
    值的两位补码二进制表示形式中的一位数

  • -返回指定的
    int
    值的两位补码二进制表示中最高阶(“最左边”)一位之前的零位数。如果指定值在其2的补码表示中没有一位,即等于零,则返回32

  • -用于以2的补码二进制形式表示int值的位数(我们都知道是32)

由于我们希望忽略前导零,
SIZE-numberOfLeadingZeros
将告诉我们实际使用的位数

public static boolean oneBitsEqualsZeroBits(int value) {
    if (value == 0)
        return false;
    int bitsUsed = Integer.SIZE - Integer.numberOfLeadingZeros(value);
    int oneBits = Integer.bitCount(value);
    int zeroBits = bitsUsed - oneBits;
    return (oneBits == zeroBits);
}
它可以缩短,虽然有点模糊,但可以解释。假设0s==1s,那么
bitCount
是1s的数量+
bitCount
是0s的数量,即
bitCount*2
是使用的位数。添加前导零的数量,应考虑
int
的所有位

public static boolean oneBitsEqualsZeroBits(int value) {
    return (value != 0 && Integer.numberOfLeadingZeros(value) + 2 * Integer.bitCount(value) == 32);
}
与长版相同版本:

public static boolean oneBitsEqualsZeroBits(long value) {
    return (value != 0 && Long.numberOfLeadingZeros(value) + 2 * Long.bitCount(value) == 64);
}
对于
biginger
,计算前导零没有意义,因为没有固定的位宽度,就没有前导零。相反,我们有一种不同的方法:

  • :返回此
    BigInteger
    的最小二补表示形式中的位数,不包括符号位
由于符号位被排除在外,我们必须将其重新添加,以与
int
long
版本保持一致

public static boolean oneBitsEqualsZeroBits(BigInteger value) {
    if (value.signum() == 0)
        return false;
    if (value.signum() > 0)
        return (2 * value.bitCount() == value.bitLength());
    return (2 * value.bitCount() == value.bitLength() + 1);
}
这三个版本将以不同的方式处理负值,因为
int
long
将分别对32位和64位进行符号扩展

测试(仅适用于
int
版本)

输出(标题手动添加到答案)

十进制十六进制结果二进制
0 0错误确定0
1错误1正常1
2正确2正常10
3错误3确定11
4 4假OK 100
8假OK 1000
9 9正常1001
10 a真正的OK 1010
11b假OK 1011
12 c正常1100
13 d假OK 1101
720387087 2AF03C0真OK 1010101111000001110000011111
-866818334 cc5566e2真实正常1100010101010110011100010
-1 ffffffff false OK 11111111111111111111111111
忽略符号

如果要在数字的字符串表示形式上比较1和0,忽略符号,即在
abs(value)
上,则可以更改方法以应用
abs()

public静态布尔oneBitsEqualsZeroBits(int值){
如果(值==0 | |值==Integer.MIN_值)
返回false;
如果(值<0)
值=-值;
返回值(Integer.numberOfLeadingZeros(值)+2*Integer.bitCount(值)==32);
}
公共静态布尔值oneBitsEqualsZeroBits(长值){
如果(值==0 | |值==Long.MIN_值)
返回false;
如果(值<0)
值=-值;
返回值(Long.numberofleadingzero(值)+2*Long.bitCount(值)==64);
}
公共静态布尔值oneBitsEqualsZeroBits(BigInteger值){
value=value.abs();
返回(value.signum()!=0&&2*value.bitCount()==value.bitLength());
}

不清楚您所说的“位字符串”是什么意思,但我认为它可能意味着任何长度的二进制序列。在原始代码中,您使用的是一个
biginger
对象,该对象不支持基本位运算符,例如
|、&&、^

但是,您的实现只支持最大值约为20亿或31位二进制数字的整数,因为整数有32位,前导位是问题中未使用的符号位。相反,只需让函数传递一个
String
变量,并让
val=new biginger(val)

从您的
binaryString
(该字符串是您的
biginger
的二进制表示形式)中,您可以简单地循环遍历字符并跟踪1和0。只需在
System.out.println(“bin=“+binaryString”)之后添加此代码

对于int版本(或long),考虑到所有尾随零都将被丢弃,可以类似地执行此操作:

int zeroes = 0;
int ones = 0;

long bitmask = 1;
// Loop stops once the one bit gone above the most significant one bit one the val
// because from that point the bitmask will always be greater than val
while (bitmask >= 0 && bitmask <= val) {
    if ((bitmask & val) == 0)
        zeroes++;
    else
        ones++;
    bitmask <<= 1; // Operator << means left shift
}
int零=0;
整数=0;
长位掩码=1;
//一旦val中的最高有效位超过一位,循环就会停止
//因为从那时起,位掩码将始终大于val

while(bitmask>=0&&bitmask如果#of 1s=val.bitCount(),那么#of 0s=binaryString.length()-val.bitCount()。有什么问题吗?尝试使用位掩码。(我很快就会写出完整版本的答案)您期望的最大数字有多大?您是从第一个1位开始计算总位,还是从类型的范围开始计算总位,例如无论值是什么,
long
总共有64位,还是
2
总共有2位?@mulliganacile这是不相关或不可取的。我试图澄清这个问题,使它更有价值猎枪式回答只会鼓励定义不清的问题。@Bohemian这个问题,以及你在这个问题上的行动,正在被讨论中。请随意参与并分享
public static boolean oneBitsEqualsZeroBits(int value) {
    if (value == 0 || value == Integer.MIN_VALUE)
        return false;
    if (value < 0)
        value = -value;
    return (Integer.numberOfLeadingZeros(value) + 2 * Integer.bitCount(value) == 32);
}

public static boolean oneBitsEqualsZeroBits(long value) {
    if (value == 0 || value == Long.MIN_VALUE)
        return false;
    if (value < 0)
        value = -value;
    return (Long.numberOfLeadingZeros(value) + 2 * Long.bitCount(value) == 64);
}

public static boolean oneBitsEqualsZeroBits(BigInteger value) {
    value = value.abs();
    return (value.signum() != 0 && 2 * value.bitCount() == value.bitLength());
}
int zeroes = 0;
int ones = 0;
for (int k = 0; k < binaryString.length(); k++) {
    if (binaryString.charAt(k) == '0')
        zeroes++;
    if (binaryString.charAt(k) == '1')
        ones++;
}
int zeroes = 0;
int ones = 0;
int bitindex = 0;
BigInteger bitmask = new BigInteger(String.valueOf("1"));
// BigInteger supports bitLength().
while (bitindex <= val.bitLength()) {
    // Bit mask has all but one bit equal zero. The AND operation cancels all
    // the bits except the one bit equal to one.
    if (bitmask.and(val).equals(BigInteger.ZERO))
        zeroes++;
    else
        ones++;

    bitindex++;
    bitmask = bitmask.shiftLeft(1);
}
int zeroes = 0;
int ones = 0;

long bitmask = 1;
// Loop stops once the one bit gone above the most significant one bit one the val
// because from that point the bitmask will always be greater than val
while (bitmask >= 0 && bitmask <= val) {
    if ((bitmask & val) == 0)
        zeroes++;
    else
        ones++;
    bitmask <<= 1; // Operator << means left shift
}