所以,假设我有一个数组:
int arr[5];
不是从 0 到 4 遍历数组,是否可以按随机顺序进行,并且迭代器不会两次遍历同一位置?
答案 0 :(得分:2)
以下所有假设您想在 O(1) 空间中实现迭代 - 不使用例如索引的辅助数组,您可以对其进行洗牌。如果你能负担得起 O(n) 的空间,那么解决方案相对容易,所以我假设你只能负担得起 O(1)。
要以随机方式迭代数组,您可以制作一个随机数生成器,并将其输出用作数组的索引。您不能以这种方式使用标准 RNG,因为它们可能会过早地两次输出相同的索引。然而,RNG 的理论相当广泛,至少有两种类型的 RNG 对其周期有保证。
使用这些理论思想:
在给定周期内制作 RNG 的技术可能太烦人而无法在代码中实现。因此,如果您事先知道数组的大小,您可以选择 N = n,并手动创建您的 RNG(分解 n 或 n+1 将是第一步)。如果您不知道数组的大小,请为 N 选择一些易于使用的数字,例如一些合适的 2 的幂。
答案 1 :(得分:1)
正如评论中提到的,您可以通过多种方式来做到这一点。最明显的方法是仅 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
您还可以实现一个自定义迭代器,该迭代器以随机顺序在一个范围内迭代而不会重复,尽管这对于您尝试实现的功能来说可能有点过头了。尝试一下,了解它是如何工作的,这仍然是一件好事。