2014-12-01 51 views
1

我有一个数字,比方说4是二进制表示为100,我希望实现的是补充数字,即用0替换1和用0替换1。我可以这样实现它二进制补码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 
+3

如何广泛被认为是输入数字?为什么'100'去代替'01111',比如说'11111011'? “10”应该转到“01”还是转到“101”? – user2357112 2014-12-01 18:22:14

+0

另外,如果输入可能太大而不适合int,那么你如何接收它们?在stdin上输入文字? – user2357112 2014-12-01 18:22:55

+1

那么使用按位否定('〜')怎么样? – fge 2014-12-01 18:22:59

回答

3

什么是最有效的方式来实现的时间复杂度同样的结果?

考虑到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); 

~运算符是一元运算符产生的值的二进制补码。循环计算最高有效位(MSB)的位置。 ((1 << msb)-1)是删除高于MSB的所有位的掩码。

Demo.

+0

注意,这也将翻转符号位,导致-5而不是3 – 2014-12-01 18:26:17

+0

@WoodrowBarlow,因此将这种操作在相当多的地方存在,难怪这里 – fge 2014-12-01 18:26:51

+0

@WoodrowBarlow你是对所有其他的编程语言,OP希望一个正数。我添加了代码来关注原始值的MSB,并根据需要屏蔽结果。谢谢! – dasblinkenlight 2014-12-01 18:33:43

1

您可以尝试使用逐否定:

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

注意,这也将翻转符号位,导致-5而不是3 – 2014-12-01 18:26:40

+0

那是我最初的尝试,但它也将reverte符号位,对于例如的System.out.println(〜4); // - 5,预计3 – sol4me 2014-12-01 18:27:15

+0

删除符号位很简单:只需按位与'整数数量。MAX_VALUE' – fge 2014-12-01 18:29:59

1

为什么不能做这样的事情:

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代码转换线...

+2

三行代码=执行了三次正则表达式搜索,比简单的循环慢得多。 – BackSlash 2014-12-01 18:31:58

+0

@BackSlash +1你打我为什么没有在我原来的职位中使用的replaceAll点,多数民众赞成 – sol4me 2014-12-01 18:33:50

+1

[这里](http://www.browxy.com/SavedCode/24946)这是一个小的演示,如果你想看到不同 – BackSlash 2014-12-01 18:54:10

0

的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);