2012-01-30 74 views
0

我一直试图做很久,但每次都失败了。我有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

你只是想创建一个唯一的随机数组的数组?或者,您是否偶尔添加了元素,这是一个长期存在的阵列?什么是用例? – 2012-01-30 21:52:41

+0

你可以使用jQuery吗? – Jivings 2012-01-30 21:53:59

+0

[在0和'x'之间生成唯一的随机数字(整数)]的可能副本(http://stackoverflow.com/q/8378870/938089?generating-unique-random-numbers-integers-between-0-and- x) – 2012-01-30 21:54:12

回答

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; 
} 

演示:http://jsfiddle.net/ZSE2w/

你并不真的需要做递归。另外,请确保length <= maximum

0

为什么不只是将值存储在字典/集内的日志中,并且不断检查您推送的每个新值是否已插入到字典/集合中。如果没有太多的价值,你不会浪费这个解决方案的太多空间。

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; 
} 
-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(); } 

最后,切片阵列只得到ñ结果:

var result = choices.slice(0, n); 
+0

Psst。 'random_function'的语法错误。你忘记了函数文字。 – 2012-01-30 22:14:20

+0

@RobW哦,对。谢谢,我现在修好了。 – Frxstrem 2012-01-30 22:27:58

+0

这不幸的是不会随机洗牌:http://www.robweir.com/blog/2010/02/microsoft-random-browser-ballot.html – 2012-01-30 22:44:47

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而变慢。