【发布时间】:2020-05-17 10:14:40
【问题描述】:
我有一个很大的整数序列 (1M+)。
每当用户查询我的 API 时,我都需要以非顺序、非随机和非重复的方式选择其中一个整数。我无法存储之前返回的所有整数的历史记录。
我想出了一个“摇动”算法,它只是在一个非常大的数组中移动值:
static int[] Shake(
int[] values,
Func<int, bool> predicate,
Func<int, int> moveBy)
{
static int Adjust(int index, int size)
{
while (index > size - 1) index -= size;
while (index < 0) index += size;
return index;
}
var count = values.Length;
for (var oldIndex = 0; oldIndex < count - 1; oldIndex++)
{
if (!predicate(oldIndex)) continue;
var newIndex = Adjust(oldIndex + moveBy(oldIndex), count);
var value = values[oldIndex];
values[oldIndex] = values[newIndex];
values[newIndex] = value;
}
return values;
}
var indexes = Enumerable.Range(0, size).ToArray();
indexes = Shake(indexes, idx => idx % 3 == 0, idx => idx + 50);
indexes = Shake(indexes, idx => idx % 2 == 0, idx => 12);
return indexes;
此算法有效,但效率不高:
- 我需要创建并循环遍历大量项目
- 可能会消耗大量内存/CPU
- 这是一个相当慢的算法
我想知道是否有另一种方法可以在 非顺序、非随机和非重复方式(可能是公式/数学系列,但我的数学很烂)。
感谢您的帮助
【问题讨论】:
-
“非顺序,非随机”对您意味着什么?您给出的示例似乎相当随机(尽管是一种非常可预测的随机性)。为什么Random.Next不够好?
标签: c# .net collections