簡體   English   中英

是否可以以隨機順序遍歷數組?

[英]Is it possible to iterate over an array in random order?

所以,假設我有一個數組:

int arr[5];

除了從 0 到 4 遍歷數組之外,是否可以按隨機順序執行此操作,並且迭代器不會 go 通過相同的 position 兩次?

以下所有內容都假設您希望在 O(1) 空間中實現迭代 - 不使用例如您可以洗牌的輔助索引數組。 如果你能負擔得起 O(n) 的空間,則解決方案相對容易,所以我假設你只能負擔 O(1)。

要以隨機方式迭代數組,您可以制作一個隨機數生成器,並將其 output 作為數組的索引。 您不能以這種方式使用標准 RNG,因為它們可以太快兩次 output 相同的索引。 但是,RNG 的理論相當廣泛,您至少有兩種類型的 RNG 可以保證它們的周期。

要使用這些理論思想:

  1. 選擇一個數字 N ≤ n(其中 n 是數組的大小),但不要比 n 大很多,這樣就可以構造一個周期為 N 的 RNG
  2. 調用您的 RNG N 次,因此它會生成從 0 到 N-1 的數字排列
  3. 對於每個數字,如果它小於數組的大小,output 是具有該索引的數組元素

制作具有給定周期的 RNG 的技術可能太煩人而無法在代碼中實現。 因此,如果您事先知道數組的大小,您可以選擇 N = n,並手動創建您的 RNG(分解 n 或 n+1 將是第一步)。 如果您不知道數組的大小,請為 N 選擇一些易於使用的數字,例如 2 的某個合適的冪。

正如評論中提到的,有幾種方法可以做到這一點。 最明顯的方法是對范圍進行shuffle ,然后對其進行迭代:

std::shuffle(arr, arr + 5);

for (int a : arr) 
  // a is a new random element from arr in each iteration

這當然會修改范圍,這可能不是您想要的。


對於不修改范圍的選項:您可以生成一系列索引,打亂這些索引並使用這些索引來索引該范圍:

int ind[5];
std::iota(ind, ind + 5, 0);
std::shuffle(ind, ind + 5);

for (int i : ind)
  // arr[i] is a new random element from arr in each iteration

您還可以實現一個自定義迭代器,該迭代器以隨機順序迭代一個范圍而不重復,盡管這對於您嘗試實現的功能來說可能是多余的。 嘗試一下,了解它是如何工作的,這仍然是一件好事。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM