У меня есть число, скажем 4, которое в двоичном выражении представлено как 100, что я хотел бы достичь, это дополнить число, т.е. заменить 1 на 0 и 0 на 1. Я могу добиться этого так
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));
}
}
Каков наиболее эффективный способ достижения такого же результата с точки зрения временной сложности? Обратите внимание, что ввод может быть очень большим числом, и нам нужно заботиться о переполнении Integer.
Обновленный отказ от числа, такого как ~ n, даст неправильный результат, например
System.out.println(~4);
outputs -5 , expected 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.
Вы можете попробовать использовать побитовое отрицание:
private int flipBits(int n) {
return ~n;
}
Почему бы не сделать что-то вроде этого:
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);
100
идет на011
вместо, скажем,11111011
? Должно ли10
идти к01
или к101
?