Java 知道什么时候有';1和0等于一个字符串的数量
对使用逐位运算符计算位字符串中1=0的数量感兴趣。如果1s=0s,则输出。有没有关于使用Java来实现这一点的想法?多谢各位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 =
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
- -返回指定的
值的两位补码二进制表示中最高阶(“最左边”)一位之前的零位数。如果指定值在其2的补码表示中没有一位,即等于零,则返回32int
- -用于以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
}