這裏是產生類似輸出到你的例子一些Python代碼:
def f(low, high):
ranges = collections.deque([(low, high)])
while ranges:
low, high = ranges.popleft()
mid = (low + high) // 2
yield mid
if low < mid:
ranges.append((low, mid))
if mid + 1 < high:
ranges.append((mid + 1, high))
實施例:
>>> list(f(0, 20))
[10, 5, 15, 2, 8, 13, 18, 1, 4, 7, 9, 12, 14, 17, 19, 0, 3, 6, 11, 16]
的low, high
範圍排除端點,如同慣例在Python,所以結果包含爲0〜19
的代碼數值,採用一個FIFO存儲仍需要處理的子範圍。 FIFO在整個範圍內初始化。在每次迭代中,下一個範圍都會彈出,並且中點會放棄。然後,如果當前範圍的下部和上部子範圍非空,則將其附加到FIFO。
編輯:這裏是C99完全不同的實現:
#include <stdio.h>
int main()
{
const unsigned n = 20;
for (unsigned i = 1; n >> (i - 1); ++i) {
unsigned last = n; // guaranteed to be different from all x values
unsigned count = 1;
for (unsigned j = 1; j < (1 << i); ++j) {
const unsigned x = (n * j) >> i;
if (last == x) {
++count;
} else {
if (count == 1 && !(j & 1)) {
printf("%u\n", last);
}
count = 1;
last = x;
}
}
if (count == 1)
printf("%u\n", last);
}
return 0;
}
這通過使用一些技巧,以確定是否爲整數已在前面的迭代已經發生避免了FIFO的必要性。因爲你知道FIFO的最大尺寸(我想它是類似於(n + 1)/ 2,但你需要仔細檢查這個),你可以使用環形緩衝區來保存排隊的範圍。
編輯2:這裏是在C99又一解決方案。它被優化爲僅執行一半循環迭代,並且僅使用位操作和添加,而不用乘法或除法。它也更加簡潔,它不包含0
的結果,所以你可以在開始時按照最初的設計進行。
for (int i = 1; n >> (i - 1); ++i) {
const int m = 1 << i;
for (int x = n; x < (n << i); x += n << 1) {
const int k = x & (m - 1);
if (m - n <= k && k < n)
printf("%u\n", x >> i);
}
}
(這是我打算從一開始就寫代碼,但我花了一些時間來環繞它我的頭。)
能否請您提供一個樣本情況下所需的完整輸出? – 2012-08-08 18:26:32
但你只能使用你分配的頁面,我是對的嗎? – 2012-08-08 18:29:44
這回答類似的問題可能會有所幫助:http://stackoverflow.com/a/11761192/1009831 – 2012-08-08 18:32:53