There is a changing rule that, 0 -> 01, 1 -> 10. For example, after the change, 10 is 1001.
Assume that the input is 0, after n changes of such rule, what is the Kth digit?
I can only come with the brutal solution, which is as followings. However I believe there exist better solutions, can anyone come up with some new ideas?
public char lalala(int n, int k) {
String str = "0";
for (int i = 0; i < n; i++) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < str.length; j++) {
if (str.charAt(j) == '0') {
sb.append("01");
} else {
sb.append("10");
}
}
str = sb.toString();
}
return str.charAt(k);
}
So your generated string will look like
0110100110010110....
Now lets write this numbers vertically and lets print binary representation of position of each digit
value|position -> position binary
-----+---------------------------
0 | 0 -> 0000
1 | 1 -> 0001
1 | 2 -> 0010
0 | 3 -> 0011
1 | 4 -> 0100
0 | 5 -> 0101
0 | 6 -> 0110
1 | 7 -> 0111
. . ....
. . ....
If you take closer look you will see that:
if number of 1 in binary representation of position is even value is 0
if number of 1 in binary representation of position is odd value is 1
which means that
0001, 0010, 0100, 0111 contains odd number of 1 value will be 1.
In other words value is equal of number of ones modulo 2.
Using this fact you can create code which will convert your n to string representing its binary form, sum all ones, and check if it is odd or even.
Code converting n to value can look like this
public static int value(int n) {
String binary = Integer.toBinaryString(n);
return binary.chars().map(e -> e == '1' ? 1 : 0).sum() % 2;
}
(little longer version if you are not familiar with streams introduced in Java 8)
public static int value(Integer n) {
String binary = Integer.toBinaryString(n);
int count = 0;
for (char ch : binary.toCharArray())
if (ch == '1') count ++;
return count % 2;
}
and when you use it like
for (int i = 0; i < 20; i++)
System.out.print(value(i));
you will get as output 01101001100101101001 which seems correct.
Related
Could you please let me know is there any best way to find that in binary representation of this number set bits are followed by unset bits only like -
4 - 100
6 - 110
8 - 1000
12 - 1100
private static boolean setBitFollowedByUnsetBits(int num) {
String str = Integer.toBinaryString(num);
int len = str.length();
int countof1 = str.indexOf('0');
int lastIndOf0 = str.lastIndexOf('0');
int countof0 = lastIndOf0 -countof1;
int lastIndOf1 = str.lastIndexOf('1');
if((!(lastIndOf1 > countof1) && (lastIndOf1 < lastIndOf0))) {
return ((num >> countof0+1)==((2 << countof1-1)-1));
}
return false;
}
This is what the logic i have written but i am looking for better solution which is much efficient .
Elaborating on #Alberto's hint:
You are looking for a bit pattern like 0000 0000 0111 1111 1100 0000 0000 0000 (I assume 32-bit integers):
some leading zero-bits (none is also OK)
a block of one-bits (at least one)
a block of zero-bits (at least one)
Special cases can be all zero-bits (N==0), or a number ending with a one-bit (having no trailing zero-bits). Let's first look at the generic case:
Having a binary number like N=xxxx1000, then N-1 is xxxx0111, replacing all the trailing zero-bits by one-bits, the rightmost one-bit by a zero-bit, and leaving the higher bits unchanged.
ORing N with N-1 like int K = N | (N-1); replaces trailing zero-bits with one-bits:
N = xxxx1000
N-1 = xxxx0111
--------
K = xxxx1111
We want the xxxx part to be something like 0001. Now, let's invert K:
~K = yyyy0000
where yyyy is the bitwise inverse of xxxx, and should look like 1110. So, once again, we can check for the trailing zero-bits and set them with int L = (~K) | ((~K)-1);. The result sould now be all one-bits if there was only one block of one-bits in the original number.
Now the special cases:
If there was no one-bit at all in N, the result will also give all ones. As the one-bits block is missing, the result should be false, needing a special handling.
A number consisting of just one block of one-bits will also result in all ones. But as the trailing zero-bits are missing, it should return false, needing a special handling as well, which just has to look at the last bit being zero.
So the code code look like:
private static boolean setBitFollowedByUnsetBits(int num) {
if (num == 0) return false;
if ((num & 1) == 1) return false;
int invK = ~ (num | (num-1));
int indicator = invK | (invK-1);
return indicator == 0xffffffff;
}
You could adapt Brian Kernigan's Algorithm
https://www.geeksforgeeks.org/count-set-bits-in-an-integer/
a) Initialize count: = 0
b) If integer n is not zero
Do bitwise & with (n-1) and assign the value back to n
{ n: = n&(n-1) }
Increment count by 1
go to step b
c) Else return count
As explained in the link above Subtraction of 1 from a number toggles all the bits (from right to left) till the rightmost set bit(including the rightmost set bit). So if we subtract a number by 1 and do bit-wise & with itself (n & (n-1)), we unset the rightmost set bit. If we do n & (n-1) in a loop and count the no of times loop executes we get the set bit count.
I think that more efficient way is to do bitwise checking instead of string -> integer transformation and operating with strings.
private static boolean check(int value) {
int h = SIZE - numberOfLeadingZeros(value);
boolean one = false;
boolean zero = false;
for (int i = h - 1; i >= 0; i--) {
int mask = 1 << i;
if ((value & mask) == mask) {
if (!zero) {
one = true;
} else {
return false;
}
} else {
if (one) {
zero = true;
} else {
return false;
}
}
}
return one && zero;
}
This is how I would do it.
private static boolean setBitFollowedByUnsetBits(int num) {
int withoutTrailingZeros = num >>> Integer.numberOfTrailingZeros(num);
return num != 0 && (withoutTrailingZeros & withoutTrailingZeros + 1) == 0;
}
This works because your problem is really to shift out the trailing zeros, which Java has a fast built in function for, then to test if the remaining number has all bits set (up to the most significant bit). You can do this with a bitwise and, as for any number n, n & n + 1 is only 0 if n has all bits set (see below). I assume you don't want 0 to return true because it has no bits set, but you can remove the num != 0 && if this isn't the case.
111 // 7
& 1000 // 8
= 0000 // 0, so 7 has all bits set
101 // 5
& 110 // 6
= 100 // 4, so 5 does not have all bits set
Edit: if the number must have some trailing zeros, you can also check for withoutTrailingZeros != num to be true.
what does this piece of code mean ...Can anyone explain how does this work..
sum += (i & (1<<j)) != 0 ? n[j] : 0;
full code:
int max = (1 << N)-1;
//System.err.println(max);
String res = "No";
for (int i = 0; i <= max; i++)
{
long sum = 0;
for (int j = 0; j < N; j++)
{
sum += (i & (1<<j)) != 0 ? n[j] : 0;
}
//System.err.println(i + " " + sum);
if(sum == m){
res = "Yes";
break;
}
Let's say that a = 0011 1100
So with the Binary Left Shift Operator (<<). The left operands value is moved left by the number of bits specified by the right operand.
A << 2 will give 240 which is 1111 0000
So in your code you have a loop for i and a loop for j
And this line
sum += (i & (1<<j)) != 0 ? n[j] : 0;
So for your second iteration of i = 2 and first iteration of j = 1
First the left shift operator will shift left all bits one position, resulting in 0000 0001 << 1 = 0000 0010 (or 2)
then you have a binary and comparison which will be i (0000 0010 in binary) & (0000 0010) = 0000 0010 (or 2)
And this and result will be asked if it's distinct of zero. If this result it's true then sum will be increased by the number in the n[j] array position, else will not be increased.
Java has a shortened version of an if else command. The use of it is very easy, once you understand it.
It’s written:
x ? y : z;
Here the question mark and the colon will take the place of the commands if and else.
This means:
condition ? inCaseOfTrue : elseCase;
With this code i & (1 << j) you get jth bit of i in binary representation. And if it equals 1 then you add n[j] to sum.
The full code shows you calculate all possible sums with selecting some elememts of array n;
I am trying to write a algorithm that will print a powerset of a given set of numbers. I did that with a loop that goes from zero to 2^length of my set. I convert the index i to binary, and whenever there is a one, I print that number. However, since the string does not have any preceding zeros, I am not getting the right output.
For example, if I have a set of three numbers: {2, 3, 4}, when i is 3, I want the string to be "011", but instead it is "11" and I'm getting an output of 2, 3 instead of 3, 4.
Here is my code:
public static void powerset (int[] A){
double powerSetLength = Math.pow(2, A.length);
for (int i=0; i<powerSetLength; i++){
String bin = Integer.toBinaryString(i);
System.out.println ("\nbin: " + bin);
for (int j=0; j<bin.length(); j++){
if (bin.charAt(j)=='1')
System.out.print(A[j] + " ");
}
}
System.out.println();
}
Here is the output that I am getting:
9 7 2
bin: 0
bin: 1
9
bin: 10
9
bin: 11
9 7
bin: 100
9
bin: 101
9 2
bin: 110
9 7
bin: 111
9 7 2
Here is an example of the output that I would like to get:
9 7 2
bin 001
2
I would like to know if there is a way to convert an integer to binary with a specified number of bits so that I can get this output.
One easy way to deal with this problem is assuming that if a digit is missing in the representation, then its value is zero. You can do it like this:
// The number of digits you want is A.length
for (int j=0; j < A.length ; j++) {
// If j is above length, it's the same as if bin[j] were zero
if (j < b.length() && bin.charAt(j)=='1')
System.out.print(A[j] + " ");
}
}
Of course if you can assume that A.length < 64 (which you should be able to assume if you want your program to finish printing in under a year) you could use long to represent your number, and bit operations to check if a bit is set or not:
int len = A.length;
for (long mask = 0 ; mask != (1L << len) ; mask++) {
for (int i = 0 ; i != len ; i++) {
if ((mask & (1L << i)) != 0) {
System.out.print(A[j] + " ");
}
}
System.out.print();
}
String padded = String.format("%03d", somenumber);
or
System.out.printf("%03d", somenumber);
Would each pad to three digits (the 3 in the format specifier). You could additionally build the specifier programatically based on length you need:
String.format("%0" + n + "d", somenumber)
But this is unnecessary if you just need to know if bit N is set. You could just as easily do this:
if ((value & (1L << n)) != 0) { }
Where value is the number, and n is the ordinal of the bit you want. This logically ands the bit in question with the value - if it's set, the result is non-zero, and the if is true. If it is not set, the result is zero, and the if is false.
On paper, binary arithmetic is simple, but as a beginning programmer, I'm finding it a little difficult to come up with algorithms for the addition, subtraction, multiplication and division of binary numbers.
I have two binary numbers stored as strings, assume that any leading zeroes have been dropped. How would I go about performing these operations on the two numbers?
Edit: I need to avoid converting them to an int or long.
Binary string to int:
int i = Integer.parseInt("10101011", 2);
int j = Integer.parseInt("00010", 2);
Then you can do anything you please with the two ints, eg:
i = i + j;
i = i - j;
And to get them back to a binary string:
String s = Integer.toBinaryString(i);
The algorithms, from wikipedia:
Addition:
The simplest arithmetic operation in
binary is addition. Adding two
single-digit binary numbers is
relatively simple, using a form of
carrying:
0 + 0 → 0
0 + 1 → 1
1 + 0 → 1
1 + 1 → 0, carry 1 (since 1 + 1 = 0 + 1 × 10 in binary)
Adding two "1" digits produces a digit
"0", while 1 will have to be added to
the next column.
Subtraction:
Subtraction works in much the same
way:
0 − 0 → 0
0 − 1 → 1, borrow 1
1 − 0 → 1
1 − 1 → 0
Subtracting a "1" digit from a "0"
digit produces the digit "1", while 1
will have to be subtracted from the
next column. This is known as
borrowing. The principle is the same
as for carrying. When the result of a
subtraction is less than 0, the least
possible value of a digit, the
procedure is to "borrow" the deficit
divided by the radix (that is, 10/10)
from the left, subtracting it from the
next positional value.
Multiplication:
Multiplication in binary is similar to
its decimal counterpart. Two numbers A
and B can be multiplied by partial
products: for each digit in B, the
product of that digit in A is
calculated and written on a new line,
shifted leftward so that its rightmost
digit lines up with the digit in B
that was used. The sum of all these
partial products gives the final
result.
Since there are only two digits in
binary, there are only two possible
outcomes of each partial
multiplication:
* If the digit in B is 0, the partial product is also 0
* If the digit in B is 1, the partial product is equal to A
For example, the binary numbers 1011
and 1010 are multiplied as follows:
1 0 1 1 (A)
× 1 0 1 0 (B)
---------
0 0 0 0 ← Corresponds to a zero in B
+ 1 0 1 1 ← Corresponds to a one in B
+ 0 0 0 0
+ 1 0 1 1
---------------
= 1 1 0 1 1 1 0
The following code implements binary addition without actually doing any arithmetic, binary or otherwise. The actual "addition" is done by lookupTable, and everything else is straight-up string manipulation. I wrote it with the intention of making it as instructive as possible, emphasizing the process instead of efficiency. Hope it helps.
public class BinaryArithmetic {
static String[] lookupTable = {
"0+0+0=00",
"0+0+1=01",
"0+1+0=01",
"0+1+1=10",
"1+0+0=01",
"1+0+1=10",
"1+1+0=10",
"1+1+1=11",
};
static String lookup(char b1, char b2, char c) {
String formula = String.format("%c+%c+%c=", b1, b2, c);
for (String s : lookupTable) {
if (s.startsWith(formula)) {
return s.substring(s.indexOf("=") + 1);
}
}
throw new IllegalArgumentException();
}
static String zeroPad(String s, int length) {
while (s.length() < length) {
s = "0" + s;
}
return s;
}
static String add(String s1, String s2) {
int length = Math.max(s1.length(), s2.length());
s1 = zeroPad(s1, length);
s2 = zeroPad(s2, length);
String result = "";
char carry = '0';
for (int i = length - 1; i >= 0; i--) {
String columnResult = lookup(s1.charAt(i), s2.charAt(i), carry);
result = columnResult.charAt(1) + result;
carry = columnResult.charAt(0);
}
if (carry == '1') {
result = carry + result;
}
return result;
}
public static void main(String args[]) {
System.out.println(add("11101", "1001"));
}
}
While we're at it, I might as well do multiply too.
static String multiply(String s1, String s2) {
String result = "";
String zeroSuffix = "";
for (int i = s2.length() - 1; i >= 0; i--) {
if (s2.charAt(i) == '1') {
result = add(result, s1 + zeroSuffix);
}
zeroSuffix += "0";
}
return result;
}
Working with binary arithmetic is really no different than the more familiar base 10. Let's take addition for example
(1) (1)
182 182 182 182 182
845 845 845 845 845
--- + --- + --- + --- + --- +
7 27 027 1027
So what did you do? You right-align the numbers to add, and you proceed right-to-left, adding one digit at a time, carrying over +1 to the left as necessary.
In binary, the process is exactly the same. In fact, it's even simpler because you only have 2 "digits" now, 0 and 1!
(1) (1) (1)
11101 11101 11101 11101 11101 11101 11101
1001 1001 1001 1001 1001 1001 1001
----- + ----- + ----- + ----- + ----- + ----- + ----- +
0 10 110 0110 00110 100110
The rest of the operations work similarly too: the same process that you use for base 10, works for base 2. And again, it's actually simpler because there are only 2 "digits", 0 and 1. This simplicity is why hardware likes the binary system.
Convert the binary strings to Integers and then operate on the Integers, e.g.
String add(String s1, String s2) {
int i1 = Integer.parseInt(s1);
int i2 = Integer.parseInt(s2);
return Integer.toBinaryString(i1 + i2);
}
The built-in BitSet class is very straight-forward to use for bit-level operations.
I'm trying to store a number as a binary string in an array but I need to specify how many bits to store it as.
For example, if I need to store 0 with two bits I need a string "00". Or 1010 with 6 bits so "001010".
Can anyone help?
EDIT: Thanks guys, as I'm rubbish at maths/programming in general I've gone with the simplest solution which was David's. Something like:
binaryString.append(Integer.toBinaryString(binaryNumber));
for(int n=binaryString.length(); n<numberOfBits; n++) {
binaryString.insert(0, "0");
}
It seems to work fine, so unless it's very inefficient I'll go with it.
Use Integer.toBinaryString() then check the string length and prepend it with as many zeros as you need to make your desired length.
Forget about home-made solutions. Use standard BigInteger instead. You can specify number of bits and then use toString(int radix) method to recover what you need (I assume you need radix=2).
EDIT: I would leave bit control to BigInteger. The object will internally resize its bit buffer to fit the new number dimension. Moreover arithmetic operations can be carried out by means of this object (you do not have to implement binary adders/multipliers etc.). Here is a basic example:
package test;
import java.math.BigInteger;
public class TestBigInteger
{
public static void main(String[] args)
{
String value = "1010";
BigInteger bi = new BigInteger(value,2);
// Arithmetic operations
System.out.println("Output: " + bi.toString(2));
bi = bi.add(bi); // 10 + 10
System.out.println("Output: " + bi.toString(2));
bi = bi.multiply(bi); // 20 * 20
System.out.println("Output: " + bi.toString(2));
/*
* Padded to the next event number of bits
*/
System.out.println("Padded Output: " + pad(bi.toString(2), bi.bitLength() + bi.bitLength() % 2));
}
static String pad(String s, int numDigits)
{
StringBuffer sb = new StringBuffer(s);
int numZeros = numDigits - s.length();
while(numZeros-- > 0) {
sb.insert(0, "0");
}
return sb.toString();
}
}
This is a common homework problem. There's a cool loop that you can write that will compute the smallest power of 2 >= your target number n.
Since it's a power of 2, the base 2 logarithm is the number of bits. But the Java math library only offers natural logarithm.
math.log( n ) / math.log(2.0)
is the number of bits.
Even simpler:
String binAddr = Integer.toBinaryString(Integer.parseInt(hexAddr, 16));
String.format("%032", new BigInteger(binAddr));
The idea here is to parse the string back in as a decimal number temporarily (one that just so happens to consist of all 1's and 0's) and then use String.format().
Note that you basically have to use BigInteger, because binary strings quickly overflow Integer and Long resulting in NumberFormatExceptions if you try to use Integer.fromString() or Long.fromString().
Try this:
String binaryString = String.format("%"+Integer.toString(size)+"s",Integer.toBinaryString(19)).replace(" ","0");
where size can be any number the user wants
Here's a simple solution for int values; it should be obvious how to extend it to e.g. byte, etc.
public static String bitString(int i, int len) {
len = Math.min(32, Math.max(len, 1));
char[] cs = new char[len];
for (int j = len - 1, b = 1; 0 <= j; --j, b <<= 1) {
cs[j] = ((i & b) == 0) ? '0' : '1';
}
return new String(cs);
}
Here is the output from a set of sample test cases:
0 1 0 0
0 -1 0 0
0 40 00000000000000000000000000000000 00000000000000000000000000000000
13 1 1 1
13 2 01 01
13 3 101 101
13 4 1101 1101
13 5 01101 01101
-13 1 1 1
-13 2 11 11
-13 3 011 011
-13 4 0011 0011
-13 5 10011 10011
-13 -1 1 1
-13 40 11111111111111111111111111110011 11111111111111111111111111110011
Of course, you're on your own to make the length parameter adequate to represent the entire value.
import java.util.BitSet;
public class StringifyByte {
public static void main(String[] args) {
byte myByte = (byte) 0x00;
int length = 2;
System.out.println("myByte: 0x" + String.valueOf(myByte));
System.out.println("bitString: " + stringifyByte(myByte, length));
myByte = (byte) 0x0a;
length = 6;
System.out.println("myByte: 0x" + String.valueOf(myByte));
System.out.println("bitString: " + stringifyByte(myByte, length));
}
public static String stringifyByte(byte b, int len) {
StringBuffer bitStr = new StringBuffer(len);
BitSet bits = new BitSet(len);
for (int i = 0; i < len; i++)
{
bits.set (i, (b & 1) == 1);
if (bits.get(i)) bitStr.append("1"); else bitStr.append("0");
b >>= 1;
}
return reverseIt(bitStr.toString());
}
public static String reverseIt(String source) {
int i, len = source.length();
StringBuffer dest = new StringBuffer(len);
for (i = (len - 1); i >= 0; i--)
dest.append(source.charAt(i));
return dest.toString();
}
}
Output:
myByte: 0x0
bitString: 00
myByte: 0x10
bitString: 001010
So here instead of 8 you can write your desired length and it will append zeros accordingly. If the length of your mentioned integer exceeds that of the number mentioned then it will not append any zeros
String.format("%08d",1111);
Output:00001111
String.format("%02d",1111);
output:1111