简体   繁体   中英

Calculate how many binary numbers with X number of 1 bits exist between two given binary numbers with the same property

This has been a challenge for me for some time.

Given two arrays that represent binary numbers, A and C with the same size, consisting of bits represented by the numbers 0 or 1, such that C > A, and both have the same X number of 1 bits, what is the most efficient way to calculate how many binaries B exist, such that A < B < C, and that every B also has X number of 1 bits?.

Example: For A={0,1,0,0,1} C={1,0,1,0,0} X=2
All B's would be {0,1,0,1,0},{0,1,1,0,0},{1,0,0,0,1},{1,0,0,1,0}, which would give me the answer 4. There are 4 binaries with 2 '1' bits between 01001 and 10100.

I have an algorithm to generate the next B given some A, but i feel that it wouldnt be efficient to keep generating the next B AND checking if i have hit the C binary yet.

Is there any way to calculate the exact number of B's between A and C without generating the B's?

Don't know if you've got an answer on https://math.stackexchange.com/ , but let me take a stab at it.

In all the discussions below, we're only interested in numbers with X 1-bits. I'm not gonna keep saying that, to keep it simpler.

So, let's assume we can calculate the count of numbers below a given value A : smaller(A) . To find the count of numbers between A and C , we can calculate that as smaller(C) - smaller(A) - 1 .

Let's define a function that counts how many numbers with X bits exists in a Y-bit space, count(X, Y) , eg count(1, 3) = 3 ( 001 , 010 , 100 ) and count(2, 3) = 3 ( 011 , 101 , 110 ). This is standard combination math, ie number of combinations to pull X balls numbered 1 to Y from a bag.

count(X, Y) = Y! / ((Y-X)! * X!)

where X! is factorial(X) .

Now I'm going to show the next part, how to calculate smaller(A) , using an example. Let A = 010010100 .

First, count the 0's on the right (2). There are then count(1, 2) numbers below A where the right-most 1-bit is moved to the right ( 010010010 , 010010001 ).

Hint: Use count = Integer.numberOfTrailingZeros(A)

Remove that 1-bit, leaving A = 010010000 .

Hint: Use A = A ^ (1 << count)

Repeat, ie count 0's (4), but this time we need count of 2-bits combinations, ie count(2, 4) .

That leaves A = 010000000 , which leads to count(3, 7) .

So, because the 1-bits were at bit 2, 4, and 7, we can calculate:

smaller(A) = count(1, 2) + count(2, 4) + count(3, 7)

Now, with a good efficient implementation of count(X, Y) , it shouldn't be too bad to calculate count of numbers between A and C, even for high bit-counts.

Anyway, that's one way to do it, but the geniuses over on the math side may have better algorithms for this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM