Number of zero bits in integer except leading zeros - java

If I have an integer in Java how do I count how many bits are zero except for leading zeros?
We know that integers in Java have 32 bits but counting the number of set bits in the number and then subtracting from 32 does not give me what I want because this will also include the leading zeros.
As an example, the number 5 has one zero bit because in binary it is 101.

Take a look at the API documentation of Integer:
32 - Integer.numberOfLeadingZeros(n) - Integer.bitCount(n)

To count non-leading zeros in Java you can use this algorithm:
public static int countNonleadingZeroBits(int i)
{
int result = 0;
while (i != 0)
{
if (i & 1 == 0)
{
result += 1;
}
i >>>= 1;
}
return result;
}
This algorithm will be reasonably fast if your inputs are typically small, but if your input is typically a larger number it may be faster to use a variation on one of the bit hack algorithms on this page.

Count the total number of "bits" in your number, and then subtract the number of ones from the total number of bits.

This what I would have done.
public static int countBitsSet(int num) {
int count = num & 1; // start with the first bit.
while((num >>>= 1) != 0) // shift the bits and check there are some left.
count += num & 1; // count the next bit if its there.
return count;
}
public static int countBitsNotSet(int num) {
return 32 - countBitsSet(num);
}

Using some built-in functions:
public static int zeroBits(int i)
{
if (i == 0) {
return 0;
}
else {
int highestBit = (int) (Math.log10(Integer.highestOneBit(i)) /
Math.log10(2)) + 1;
return highestBit - Integer.bitCount(i);
}
}

Since evaluation order in Java is defined, we can do this:
public static int countZero(int n) {
for (int i=1,t=0 ;; i<<=1) {
if (n==0) return t;
if (n==(n&=~i)) t++;
}
}
Note that this relies on the LHS of an equality being evaluated first; try the same thing in C or C++ and the compiler is free to make you look foolish by setting your printer on fire.

Related

Program to sum the odd digits recursively

Using recursion, If n is 123, the code should return 4 (i.e. 1+3). But instead it is returning the last digit, in this case 3.
public static int sumOfOddDigits(NaturalNumber n) {
int ans = 0;
if (!n.isZero()) {
int r = n.divideBy10();
sumOfOddDigits(n);
if (r % 2 != 0) {
ans = ans + r;
}
n.multiplyBy10(r);
}
return ans;
}
It isn't clear what NaturalNumber is or why you would prefer it to int, but your algorithm is easy enough to follow with int (and off). First, you want the remainder (or modulus) of division by 10. That is the far right digit. Determine if it is odd. If it is add it to the answer, and then when you recurse divide by 10 and make sure to add the result to the answer. Like,
public static int sumOfOddDigits(int n) {
int ans = 0;
if (n != 0) {
int r = n % 10;
if (r % 2 != 0) {
ans += r;
}
ans += sumOfOddDigits(n / 10);
}
return ans;
}
One problem is that you’re calling multiplyBy on n and not doing anything with the result. NaturalNumber seems likely to be immutable, so the method call has no effect.
But using recursion lets you write declarative code, this kind of imperative logic isn’t needed. instead of mutating local variables you can use the argument list to hold the values to be used in the next iteration:
public static int sumOfOddDigits(final int n) {
return sumOfOddDigits(n, 0);
}
// overload to pass in running total as an argument
public static int sumOfOddDigits(final int n, final int total) {
// base case: no digits left
if (n == 0)
return total;
// n is even: check other digits of n
if (n % 2 == 0)
return sumOfOddDigits(n / 10, total);
// n is odd: add last digit to total,
// then check other digits of n
return sumOfOddDigits(n / 10, n % 10 + total);
}

How to calculate the number of zeros in binary?

Hi I am making a method that can take an integer as a parameter and compute how many zeros its binary form has. So for example, if I have binaryZeros(44), its binary form is 101100. Therefore, binaryZeros(44) should return 3. However, I am making some errors and I cannot tell where it is coming from. I would appreciate it if someone can point out where I am making that error, or if my approach (logic) to this problem is good enough. Thank you!
My code is Below:
public static int binaryZeros(int n) {
int zeroCount = 0;
double m = n;
while (m >= 0.0) {
m = m / 2.0;
if (m == Math.floor(m)) {
zeroCount++;
} else {
m = Math.floor(m);
}
}
return zeroCount;
}
Below is a more concise way to solve this problem
public static int binaryZeros(int n) {
int zeroCount = 0;
// Run a while loop until n is greater than or equals to 1
while(n >= 1)
{
/* Use modulo operator to get the reminder of division by 2 (reminder will be 1 or 0 as you are dividing by 2).
Keep in mind that binary representation is an array of these reminders until the number is equal to 1.
And once the number is equal to 1 the reminder is 1, so you can exit the loop there.*/
if(n % 2 == 0)
{
zeroCount++;
}
n = n / 2;
}
return zeroCount;
}
Your approach is good, but I think there's a better way to do it. The Integer class has a static method that returns the binary of a number: Integer.toBinaryString(num) . This will return a String.
Then, you can just check if there are any 0 in that string with method that has a for loop and evaluating with an if:
public int getZeros(String binaryString){
int zeros = 0;
for(int i=0; i < binaryString.length; i++)
if(binaryString.charAt[i].equals('0')
zeros++;
return zeros;
}
I believe this would be a simpler option and it doesn't have any errors.
Once m == 0.0, it will never change, so your while loop will never stop.
If you start with a number m >= 0, it can never become negative no matter how many times you divide it by 2 or use Math.floor. The loop should stop when m reaches 0, so change the condition to while (m > 0.0).
Note that you could do the same thing with built-in standard library methods. For example, there is a method that returns the number of leading zeros in a number, and a method that returns the number of bits set to 1. Using both you can compute the number of zeros that are not leading zeros:
static int binaryZeros(int n) {
return Integer.SIZE - Integer.numberOfLeadingZeros(n) - Integer.bitCount(n);
}
Here is one way. It simply complements the integer reversing 1's and 0's and then counts the 1 bits. You should not be using floating point math when doing this.
~ complements the bits
&1 masks the low order bit. Is either 1 or 0
>>> shifts right 1 bit including sign bit.
System.out.println(binaryZeros(44) + " (" +Integer.toBinaryString(44) +")");
System.out.println(binaryZeros(-44) + " ("Integer.toBinaryString(-44)+")");
public static int binaryZeros(int v) {
int count = 0;
while (v != 0) {
// count 1 bits
// of ~v
count += (~v)&1;
v >>>=1;
}
return count;
}
Prints
3 (101100)
4 (11111111111111111111111111010100)
Just be simple, whe there's Integer.bitCount(n) method:
public static int binaryZeros(int n) {
long val = n & 0xFFFFFFFFL;
int totalBits = (int)(Math.log(val) / Math.log(2) + 1);
int setBits = Long.bitCount(val);
return totalBits - setBits;
}
public static int getZeros(int num) {
String str= Integer.toBinaryString(num);
int count=0;
for(int i=0; i<str.length(); i++) {
if(str.charAt(i)=='0') count++;
}
return count;
}
The method toBinaryString() returns a string representation of the integer argument as an unsigned integer in base 2. It accepts an argument in Int data-type and returns the corresponding binary string.
Then the for loop counts the number of zeros in the String and returns it.

count Number of 1 Bits in java

I encountered a strange problem while doing an leetcode problem. This is about bits representation in Java.
Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also known as the Hamming weight).
For example, the 32-bit integer ’11' has binary representation 00000000000000000000000000001011, so the function should return 3.
My solution is
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int count = 0;
for(int i = 0; i < 32; ++i){
if((n >>> i) % 2 == 1){
++count;
}
}
return count;
}
}
This code is not accepted because of the input case:
4294967295 (11111111111111111111111111111111)
I reviewed the bit representation of integer in java but still do not know the problem of the solution?
Could anyone help me?
public int hammingWeight(int n) {
return Integer.bitCount(n);
}
Integer.bitCount(int i)
Returns the number of one-bits in the two's complement binary
representation of the specified int value.
The issue is performing modulo when you want a bitwise &. Something like,
public static int hammingWeight(int n) {
int count = 0;
for (int i = 0; i < 32; ++i) {
if (((n >>> i) & 1) == 1) {
++count;
}
}
return count;
}
public static void main(String[] args) {
int c = -1;
System.out.println(hammingWeight(c));
}
Outputs (as expected)
32
Java uses twos compliment. So the negative bit is the far left one. That means if you have a number greater than Integer.MAX_VALUE your input will be a negative number. When you do %2the sign remains unchanged. An alternative would be to use &1which will change the sign bit. After the first iteration, and you have done a bit shift, the sign bit will be zero.

Changing numbers places in java

Can anyone please learn me how to change this number 5486 to 4568 ? I need to change two pairs of numbers places. Any ideas please?
My code :
public Number shiftRight(int n) {
int length = (getNumOfDigits()+MINUSONE);
length = (int) Math.pow(TEN, length);
for (int i=0; i<n; i++){
int m=num%TEN;
num=(m*length) + (num/TEN);
}
return new Number(num);
}
public int shiftRightDistance(Number other){
int max = getNumOfDigits();
for (int i=0;i<max;i++)
{
if(compareTo(shiftRight(i))==ZERO)
{
return i;
}
}
return MINUSONE;
}
public Number swapPairs() {
}
}
The simplest (and least confusing) thing might be to convert the number to a char array, swap pairs of characters, and then convert back to a number. You can use String.valueOf(int), String.toCharArray(), new String(char[]) and Integer.valueOf(String) to put that together.
Alternatively, you can build on the following method that swaps the digits of a non-negative number less than 100:
private int swapDigitsLessThan100(int n) {
return 10 * (n % 10) + n / 10;
}
The way to build on that would be to extract every pair of digits from the original number, working recursively. The following deals with numbers that are an even number of digits long:
public int swapDigits(int n) {
if (n == 0) {
return 0;
return 100 * swapDigits(n / 100) + swapDigitsLessThan100(n % 100);
}
With this code, if n is an odd number of digits, the result will be to use a leading 0 as an additional digit.

Bit mask generation to minimize number of 1

In order to explore some solutions, I need to generate all possibilities. I'm doing it by using bit masking, like this:
for (long i = 0; i < 1L << NB; i++) {
System.out.println(Long.toBinaryString(i));
if(checkSolution(i)) {
this.add(i); // add i to solutions
}
}
this.getBest(); // get the solution with lowest number of 1
this allow me to explore (if NB=3):
000
001
010
011
100
101
110
111
My problem is that the best solution is the one with the lowest number of 1.
So, in order to stop the search as soon as I found a solution, I would like to have a different order and produce something like this:
000
001
010
100
011
101
110
111
That would make the search a lot faster since I could stop as soon as I get the first solution. But I don't know how can I change my loop to get this output...
PS: NB is undefined...
The idea is to turn your loop into two nested loops; the outer loop sets the number of 1's, and the inner loop iterates through every combination of binary numbers with N 1's. Thus, your loop becomes:
for (long i = 1; i < (1L << NB); i = (i << 1) | 1) {
long j = i;
do {
System.out.println(Long.toBinaryString(j));
if(checkSolution(j)) {
this.add(j); // add j to solutions
}
j = next_of_n(j);
} while (j < (1L << NB));
}
next_of_n() is defined as:
long next_of_n(long j) {
long smallest, ripple, new_smallest, ones;
if (j == 0)
return j;
smallest = (j & -j);
ripple = j + smallest;
new_smallest = (ripple & -ripple);
ones = ((new_smallest / smallest) >> 1) - 1;
return (ripple | ones);
}
The algorithm behind next_of_n() is described in C: A Reference Manual, 5th edition, section 7.6, while showing an example of a SET implementation using bitwise operations. It may be a little hard to understand the code at first, but here's what the book says about it:
This code exploits many unusual properties of unsigned arithmetic. As
an illustration:
if x == 001011001111000, then
smallest == 000000000001000
ripple == 001011010000000
new_smallest == 000000010000000
ones == 000000000000111
the returned value == 001011010000111
The overall idea is that you find the rightmost contiguous group of
1-bits. Of that group, you slide the leftmost 1-bit to the left one
place, and slide all the others back to the extreme right. (This code
was adapted from HAKMEM.)
I can provide a deeper explanation if you still don't get it. Note that the algorithm assumes 2 complement, and that all arithmetic should ideally take place on unsigned integers, mainly because of the right shift operation. I'm not a huge Java guy, I tested this in C with unsigned long and it worked pretty well. I hope the same applies to Java, although there's no such thing as unsigned long in Java. As long as you use reasonable values for NB, there should be no problem.
This is an iterator that iterates bit patterns of the same cardinality.
/**
* Iterates all bit patterns containing the specified number of bits.
*
* See "Compute the lexicographically next bit permutation"
* http://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation
*
* #author OldCurmudgeon
*/
public class BitPattern implements Iterable<BigInteger> {
// Useful stuff.
private static final BigInteger ONE = BigInteger.ONE;
private static final BigInteger TWO = ONE.add(ONE);
// How many bits to work with.
private final int bits;
// Value to stop at. 2^max_bits.
private final BigInteger stop;
// Should we invert the output.
private final boolean not;
// All patterns of that many bits up to the specified number of bits - invberting if required.
public BitPattern(int bits, int max, boolean not) {
this.bits = bits;
this.stop = TWO.pow(max);
this.not = not;
}
// All patterns of that many bits up to the specified number of bits.
public BitPattern(int bits, int max) {
this(bits, max, false);
}
#Override
public Iterator<BigInteger> iterator() {
return new BitPatternIterator();
}
/*
* From the link:
*
* Suppose we have a pattern of N bits set to 1 in an integer and
* we want the next permutation of N 1 bits in a lexicographical sense.
*
* For example, if N is 3 and the bit pattern is 00010011, the next patterns would be
* 00010101, 00010110, 00011001,
* 00011010, 00011100, 00100011,
* and so forth.
*
* The following is a fast way to compute the next permutation.
*/
private class BitPatternIterator implements Iterator<BigInteger> {
// Next to deliver - initially 2^n - 1
BigInteger next = TWO.pow(bits).subtract(ONE);
// The last one we delivered.
BigInteger last;
#Override
public boolean hasNext() {
if (next == null) {
// Next one!
// t gets v's least significant 0 bits set to 1
// unsigned int t = v | (v - 1);
BigInteger t = last.or(last.subtract(BigInteger.ONE));
// Silly optimisation.
BigInteger notT = t.not();
// Next set to 1 the most significant bit to change,
// set to 0 the least significant ones, and add the necessary 1 bits.
// w = (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctz(v) + 1));
// The __builtin_ctz(v) GNU C compiler intrinsic for x86 CPUs returns the number of trailing zeros.
next = t.add(ONE).or(notT.and(notT.negate()).subtract(ONE).shiftRight(last.getLowestSetBit() + 1));
if (next.compareTo(stop) >= 0) {
// Dont go there.
next = null;
}
}
return next != null;
}
#Override
public BigInteger next() {
last = hasNext() ? next : null;
next = null;
return not ? last.not(): last;
}
#Override
public void remove() {
throw new UnsupportedOperationException("Not supported.");
}
#Override
public String toString () {
return next != null ? next.toString(2) : last != null ? last.toString(2): "";
}
}
public static void main(String[] args) {
System.out.println("BitPattern(3, 10)");
for (BigInteger i : new BitPattern(3, 10)) {
System.out.println(i.toString(2));
}
}
}
First you loop over your number of ones, say n. First you start with 2^n-1, which is the first integer to contain exactly n ones and test it. To get the next one, you use the algorithm from Hamming weight based indexing (it's C code, but should not be to hard to translate it to java).
Here's some code I put together some time ago to do this. Use the combinadic method giving it the number of digits you want, the number of bits you want and which number in the sequence.
// n = digits, k = weight, m = position.
public static BigInteger combinadic(int n, int k, BigInteger m) {
BigInteger out = BigInteger.ZERO;
for (; n > 0; n--) {
BigInteger y = nChooseK(n - 1, k);
if (m.compareTo(y) >= 0) {
m = m.subtract(y);
out = out.setBit(n - 1);
k -= 1;
}
}
return out;
}
// Algorithm borrowed (and tweaked) from: http://stackoverflow.com/a/15302448/823393
public static BigInteger nChooseK(int n, int k) {
if (k > n) {
return BigInteger.ZERO;
}
if (k <= 0 || k == n) {
return BigInteger.ONE;
}
// ( n * ( nChooseK(n-1,k-1) ) ) / k;
return BigInteger.valueOf(n).multiply(nChooseK(n - 1, k - 1)).divide(BigInteger.valueOf(k));
}
public void test() {
System.out.println("Hello");
BigInteger m = BigInteger.ZERO;
for ( int i = 1; i < 10; i++ ) {
BigInteger c = combinadic(5, 2, m);
System.out.println("c["+m+"] = "+c.toString(2));
m = m.add(BigInteger.ONE);
}
}
Not sure how it matches up in efficiency with the other posts.

Categories

Resources