我一直试图这么做但是每次都失败了。我有var rand = Math.floor(Math.random() * 5);
和log.push(rand);
。为了确保它不重复任何值,我尝试:
function dontRepeat() {
var g = 0;
for (var i = 0; i < log.length; i++) {
if (log[log.length - i] == rand) g++;
if (g > 1) {
rand = Math.floor(Math.random() * n);
dontRepeat();
}
}
}
请帮我找出问题所在。
答案 0 :(得分:1)
为什么不这样做:
function unique_randoms(length, maximum) {
var numbers = [];
var test;
for (var i = 0; i < length; i++) {
do {
test = Math.floor(Math.random() * maximum);
} while (numbers.indexOf(test) != -1);
numbers.push(test);
}
return numbers;
}
你真的不需要做递归。另外,请确保length <= maximum
。
答案 1 :(得分:0)
为什么不将值存储在字典/集内的日志中,并继续检查您正在推送的每个新值,无论它是否已插入字典/集中。如果没有太多的值,那么这个解决方案就不会浪费那么多空间。
答案 2 :(得分:0)
跟踪已使用的数字作为对象的属性(在这种情况下,您可能会从常量属性查找中受益),(未经测试):
function getNonDuplicateRandoms(n, max) {
var used={}, numbers=[], rand, i;
if (n > max) throw new Error("n > max");
for (i=0; i<n; i++) {
do {
rand = Math.floor(Math.random() * max);
} while (used[rand]);
numbers.push(rand);
used[rand] = true;
}
return numbers;
}
答案 3 :(得分:0)
首先制作有序数组,您可以获得重复的免费列表:
A = [];
for(i=0; i<n; i++) A[i]=i;
然后洗牌:
for(i=0; i<n; i++) {
r = Math.floor(Math.random() * (i + 1));
swap = A[i];
A[i] = A[r];
A[r] = swap;
}
现在将您需要的内容提升到n
。如果n
非常大,则会占用大量内存,在这种情况下,使用indexOf
方法测试已经使用的内容可能更有效。但是,这种方法很慢,并且随着您需要的项目数量接近n
而变慢。
答案 4 :(得分:-1)
最明显的解决方案 - 记录所有结果并保持随机生成数字 - 是无效的,因为它是随机的,而且据你所知,它可以随机生成与你已经生成的相同的数字,接近永恒(非常不可能,但仍然)。
最简单,最有效的方法,至少在可管理的可能范围内,是为了做出一系列可能的选择:
var choices = [1, 2, 3, 4];
然后使用Array.sort()
:
// Randomization function, to sort randomly
var random_function = function(x, y) { return 0.5 - Math.random(); }
choices.sort(random_function);
或者,在一行中:
choices.sort(function(x,y) { return 0.5 - Math.random(); }
最后,将数组切片为仅获取 n 结果:
var result = choices.slice(0, n);