是否有任何有效的演算法可以做到這一點,我試圖產生所有二進制數并將它們存盤在一個陣列中然后對它們進行排序,如果我們可以直接按字典順序生成二進制數,代碼會快得多。例如:n=7 產生 1,10,100,101,11,110,111
uj5u.com熱心網友回復:
這里的關鍵屬性是, 0
will always come before 1
,所以你可以使用遞回來解決這個問題。該演算法看起來像:
- 從開始遞回
1
- 如果當前數字 >
n
,忽略它 - 否則,將其添加到輸出串列中。打電話
recursion(curr_number "0")
和recursion(curr_number "1")
這是一個簡單的演算法,可以在大多數語言中輕松實作。
編輯:Python實作:
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))
uj5u.com熱心網友回復:
如果對一棵完整的二叉樹逐行編號,從 1 到 2^d-1,按字典順序的節點列舉就是前序遍歷。現在,當一個節點的兩個子節點攜帶父節點的值后跟 0 或 1 時,我們就有了遞回列舉
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)
(您還可以通過連接 0 或 1 來獲得二進制表示。)
uj5u.com熱心網友回復:
您可以遵循一些規則來生成任何字串集的字典順序中的下一個專案:
- 第一個改變的符號必須增加(否則你會得到一個更早的符號)
- 更改的第一個符號必須盡可能靠右(否則會出現較小的字典變化);和
- 第一次更改后的符號必須盡可能小(否則會再次出現較小的詞典更改)。
對于排序二進制字串,這些規則很容易應用。在每次迭代中:
- 如果您可以在不超過 的情況下附加零
n
,那么就這樣做; - 否則,找到最右邊的可能 0,將其更改為 1,然后洗掉其余部分。在這種情況下,“最右邊的可能 0”是產生結果 <= n 的最右邊的一個。如果 n 不是 2 x -1 ,這不一定是最右邊的。
這種迭代很容易用按位運算子實作,從而產生了這個很好的快速演算法。為了簡化步驟 (2),我們假設 n 是 2 x -1 并檢查我們的輸出:
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
在線嘗試
通常情況下,這種迭代演算法比遞回演算法快得多,但要想出它需要對解決方案的結構有更深入的了解。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/443791.html
上一篇:模運算-證明或反駁計算