Reputation: 21
Is there any efficient algorithm to do so ,I have tried to produce all binary numbers and store them in an array then sort them, if we can directly generate the binary numbers in lexicographical order the code will be much faster. For eg : n=7 produces 1,10,100,101,11,110,111
Upvotes: 2
Views: 632
Reputation: 59253
There are a few rules you can follow to generate the next item in a lexicographical ordering of any set of strings:
For ordering the binary strings, these rules are easy to apply. In each iteration:
n
, then do so;This iteration is pretty easy to implement with bitwise operators, leading to this nice quick algorithm. To simplify step (2), we assume that n is 2x-1 and just check our outputs:
def printLexTo(n):
val=1
while True:
if val<=n:
print("{0:b}".format(val))
if 2*val <= n:
val *= 2
else:
# get the smallest 0 bit
bit = (val+1) & ~val
# set it to 1 and remove the remainder
val = (val+1)//bit
if val==1:
# there weren't any 0 bits in the string
break
As is often the case, this iterative algorithm is a lot faster than recursive ones, but coming up with it requires a deeper understanding of the structure of the solution.
Upvotes: 1
Reputation:
If you number a complete binary tree row by row, from 1 to 2^d-1, the enumeration of the nodes in lexicographical order is the preorder traversal. Now as the two children of a node carry the value of the parent followed by 0 or by 1, we have the recursive enumeration
n= ...
def Emit(m):
print(bin(m))
if 2 * m <= n:
Emit(2 * m)
if 2 * m + 1 <= n:
Emit(2 * m + 1)
Emit(1)
(You can also obtain the binary representations by concatenating 0's or 1's as you go.)
Upvotes: 1
Reputation: 8111
The key property here is, 0
will always come before 1
, so you can use recursion to solve this. The algorithm would look like:
1
n
, ignore itrecursion(curr_number + "0")
and recursion(curr_number + "1")
This is a simple algorithm, which can be easily implemented in most languages.
Edit: Python implementation:
def dfs(current_string, current_number, n):
if current_number > n:
return []
strings = [current_string]
strings.extend(dfs(current_string + "0", current_number << 1, n))
strings.extend(dfs(current_string + "1", (current_number << 1)+1, n))
return strings
print(dfs("1", 1, 7))
Upvotes: 2