Java 二进制补码0到1,1到0

Java 二进制补码0到1,1到0,java,algorithm,Java,Algorithm,我有一个数字,比如说4,用二进制表示为100,我想实现的是对这个数字进行补码,即用0替换1,用1替换0。我可以做到这一点 public class Foo { public static void main(String[] args) { String binaryString = Integer.toBinaryString(4); StringBuilder out = new StringBuilder(); char[] cha

我有一个数字,比如说4,用二进制表示为100,我想实现的是对这个数字进行补码,即用0替换1,用1替换0。我可以做到这一点

public class Foo {
    public static void main(String[] args) {
        String binaryString = Integer.toBinaryString(4);

        StringBuilder out = new StringBuilder();
        char[] chars = binaryString.toCharArray();
        char x;
        for (char ch : chars) {
            if (ch == '1') {
                x = '0';
            } else {
                x = '1';
            }
            out.append(x);
        }
        System.out.println(Integer.parseInt(out.toString(), 2));
    }
}
在时间复杂度方面,实现相同结果的最有效方法是什么?请注意,输入可以是非常大的数字,我们需要注意整数溢出

已更新 对像~n这样的数字求反会得到错误的结果,例如

System.out.println(~4); 
outputs -5 , expected 3 

您可以尝试使用位求反:

private int flipBits(int n) {
     return ~n;
}

您可以尝试使用位求反:

private int flipBits(int n) {
     return ~n;
}
在时间复杂度方面,实现相同结果的最有效方法是什么

假设
int
的大小固定为32,则时间复杂度为O(1)。但是,您的程序效率很低,因为它创建了一组字符串,进行字符串解析,等等

如果完全跳过到二进制的转换,并简单地反转数字,则可以更快地执行此操作,如下所示:

int val = 4;
int msb = int msb = 32 - Integer.numberOfLeadingZeros(val);
int inverse = ~val & ((1 << msb)-1);
System.out.println(inverse);
public static void main(String[] args) {
        String binaryString = Integer.toBinaryString(4);
        binaryString = binaryString.replaceAll("1", "-");
        binaryString = binaryString.replaceAll("0", "1");
        binaryString = binaryString.replaceAll("-", "0");
int val=4;
int msb=int msb=32-整数。前导零的数量(val);
int逆=~val&((1)
在时间复杂度方面,实现相同结果的最有效方法是什么

考虑到
int
的大小固定为32,时间复杂度为O(1)。但是,您的程序效率非常低,因为它会创建一组字符串,并进行字符串解析,等等

如果完全跳过到二进制的转换,并简单地反转数字,则可以更快地执行此操作,如下所示:

int val = 4;
int msb = int msb = 32 - Integer.numberOfLeadingZeros(val);
int inverse = ~val & ((1 << msb)-1);
System.out.println(inverse);
public static void main(String[] args) {
        String binaryString = Integer.toBinaryString(4);
        binaryString = binaryString.replaceAll("1", "-");
        binaryString = binaryString.replaceAll("0", "1");
        binaryString = binaryString.replaceAll("-", "0");
int val=4;
int msb=int msb=32-整数。前导零的数量(val);

int inverse=~val&(1为什么不这样做:

int val = 4;
int msb = int msb = 32 - Integer.numberOfLeadingZeros(val);
int inverse = ~val & ((1 << msb)-1);
System.out.println(inverse);
public static void main(String[] args) {
        String binaryString = Integer.toBinaryString(4);
        binaryString = binaryString.replaceAll("1", "-");
        binaryString = binaryString.replaceAll("0", "1");
        binaryString = binaryString.replaceAll("-", "0");

只有3行代码要转换…

为什么不这样做:

int val = 4;
int msb = int msb = 32 - Integer.numberOfLeadingZeros(val);
int inverse = ~val & ((1 << msb)-1);
System.out.println(inverse);
public static void main(String[] args) {
        String binaryString = Integer.toBinaryString(4);
        binaryString = binaryString.replaceAll("1", "-");
        binaryString = binaryString.replaceAll("0", "1");
        binaryString = binaryString.replaceAll("-", "0");

只有3行代码可以转换…

BigInteger允许您使用任意长度。求反的方法是找到给定输入长度的最大值,并从中减去输入值

   //you might want to validate that the string really is a binary number string
    BigInteger myNum = new BigInteger(inputStr, 2);
    BigInteger max = new BigInteger("2");
    max = max.pow(inputStr.length()).subtract(new BigInteger("1"));
    BigInteger ans = max.substract(myNum);

BigInteger允许您使用任意长度的数字。求反的方法是找到给定输入长度的最大值,并从中减去输入值

   //you might want to validate that the string really is a binary number string
    BigInteger myNum = new BigInteger(inputStr, 2);
    BigInteger max = new BigInteger("2");
    max = max.pow(inputStr.length()).subtract(new BigInteger("1"));
    BigInteger ans = max.substract(myNum);



输入数字的宽度是多少?为什么
100
转到
011
而不是,比如说,
11111 011
?应该
10
转到
01
还是
101
?另外,如果输入太大而无法放入int,您是如何接收它们的?在stdin上的文本输入?以及如何使用位求反(
~
)?转换为字符串并使用.replaceAll()@用户2357112,因为输入是数字4,用二进制100表示,我们需要对该数字求反。一般来说,输入可以是任何正数,我们需要对该数字求反。输入数字的宽度是多少?为什么
100
转到
011
,而不是说
11111 011
?应该
10
转到
01
101
?此外,如果输入太大而无法放入整数,您是如何接收它们的?在stdin上输入文本?使用位求反(
~
)怎么样?转换为字符串并使用。replaceAll()@user2357112,因为输入是数字4,用二进制100表示,我们需要对该数字求反。一般来说,输入可以是任何正数,我们需要对该数字求反。请注意,这也会翻转符号位,导致-5而不是3。@WoodrowBarlow以及几乎所有其他编程语言中的该运算符它存在的年代,毫不奇怪here@WoodrowBarlow你是对的,OP需要一个正数。我添加了代码以关注原始值的MSB,并根据需要屏蔽结果。谢谢!@sol4me Yes,对于
long
,您将使用63的
MSB
,并将
L
添加到常量
1
(即
(1L它看起来像
msb=32-Integer.numberOfLeadingZeros(val)
?请注意,这也将翻转符号位,结果是-5而不是3。@WoodrowBarlow以及几乎所有其他编程语言中存在的该运算符,这并不奇怪here@WoodrowBarlow您是对的,OP需要一个正数。我添加了代码以注意原始值的MSB,并将结果屏蔽为required。谢谢!@sol4me是的,对于
long
,您将使用63的
msb
,并将
L
添加到常量
1
(即
(1L它看起来像
msb=32-整数。numberofleadingzero(val)
?请注意,这也会翻转符号位,结果是-5而不是3。这是我最初的尝试,但它也会还原符号位,例如System.out.println(~4);//-5,预期3删除符号位很容易:只需按位和带有
整数的数字。MAX_VALUE
@fge你是说
~n&Integer.MAX_VALUE
?这似乎不起作用。@WoodrowBarlow不确定这里的运算符的优先级,但对于parens,
~(n&Integer.MAX_VALUE)
。请注意,这也会翻转符号位,结果是-5而不是3。这是我最初的尝试,但也会还原符号位,例如System.out.println(~4);//-5,预期3删除符号位很容易:只需按位和带有
整数的数字。MAX_VALUE
@fge你是说
~n&Integer.MAX_VALUE
?这似乎不起作用。@WoodrowBarlow不确定这里的运算符的优先级,但对于parens,
~(n&Integer.MAX_VALUE)
.Three lines of code=执行了三次正则表达式搜索,这比简单循环慢得多。@Backslax+1你说到点子上了,这就是为什么我在我的原始帖子中没有使用replaceAll的原因。如果你想看到不同的三行代码=执行了三次正则表达式搜索,这比简单循环慢得多。@Backslax+1你说到点子上了,这就是为什么我在我的原始帖子中没有使用replaceAll的原因。如果你想看到区别的话,这只是一个小演示