除一个数字之外的某个范围内的随机整数

时间:2015-12-09 15:32:13

标签: javascript random

我想在一个范围内得到一个随机数,不包括一个数字(例如从1到1000不包括577)。我搜索了一个解决方案,但从未解决过我的问题。

我想要类似的东西:

Math.floor((Math.random() * 1000) + 1).exclude(577);

我想避免for循环尽可能多地创建数组,因为长度总是不同的(有时是1到10000,有时是685到888555444等),生成它的过程可能需要太多时间了。

我已经尝试过:

我怎么能实现这个目标?

8 个答案:

答案 0 :(得分:21)

获取某个范围[a, b]中的随机整数的最快方法是在ca之间生成它,不包括一个b-1 {1}},如果它高于或等于c,则将其递增1。

这是一个有效的功能:

function randomExcluded(min, max, excluded) {
    var n = Math.floor(Math.random() * (max-min) + min);
    if (n >= excluded) n++;
    return n;
}

此解决方案只有complexity的O(1)。

答案 1 :(得分:3)

一种可能性是不添加1,如果该数字出来,则指定最后一个可能的值。

例如:

var result = Math.floor((Math.random() * 100000));
if(result==577) result = 100000;

通过这种方式,您不需要重新启动随机方法,但会重复。并且符合随机的目标。

答案 2 :(得分:2)

正如@ebyrob建议的那样,你可以创建一个函数,通过为每个大于或等于的值加1,从较小的集到具有排除值的较大集进行映射:

// min - integer
// max - integer
// exclusions - array of integers
//            - must contain unique integers between min & max
function RandomNumber(min, max, exclusions) {
    // As @Fabian pointed out, sorting is necessary 
    // We use concat to avoid mutating the original array
    // See: http://stackoverflow.com/questions/9592740/how-can-you-sort-an-array-without-mutating-the-original-array
    var exclusionsSorted = exclusions.concat().sort(function(a, b) {
        return a - b
    });

    var logicalMax = max - exclusionsSorted.length;
    var randomNumber = Math.floor(Math.random() * (logicalMax - min + 1)) + min;

    for(var i = 0; i < exclusionsSorted.length; i++) {
        if (randomNumber >= exclusionsSorted[i]) {
            randomNumber++;
        }
    }

    return randomNumber;
}

Example Fiddle

另外,我认为@ JesusCuesta的回答提供a simpler mapping并且更好。

更新:我原来的回答中有许多问题。

答案 3 :(得分:1)

您可以继续生成该号码,直到您发现它符合您的需求为止:

function randomExcluded(start, end, excluded) {
    var n = excluded
    while (n == excluded)
        n = Math.floor((Math.random() * (end-start+1) + start));
    return n;
}

myRandom = randomExcluded(1, 10000, 577);

顺便说一下,这不是最好的解决方案,请查看my other answer以获得更好的解决方案!

答案 4 :(得分:1)

扩展@Jesus Cuesta的回答:

function RandomNumber(min, max, exclusions) {
    var hash = new Object();
    for(var i = 0; i < exclusions.length; ++i ) {  // TODO: run only once as setup
       hash[exclusions[i]] = i + max - exclusions.length;
    }
    var randomNumber = Math.floor((Math.random() * (max - min - exclusions.length)) + min);
    if (hash.hasOwnProperty(randomNumber)) {
       randomNumber = hash[randomNumber];
    }
    return randomNumber;
}

注意:这仅适用于max - exclusions.length&gt;最大限度的排除。很近。

答案 5 :(得分:0)

因此,我们的想法是再次调用该函数,具体取决于您要排除的值。

所以看看这个例子

function generateRandom(min, max,valuetoexclude) {
    var num = Math.floor(Math.random() * (max - min + 1)) + min;
    return (num === valuetoexclude) ? generateRandom(min, max) : num;
}

var test = generateRandom(1, 10000,577)

答案 6 :(得分:0)

生成随机数,如果匹配排除的数字,则添加另一个随机数(-20到20)

var max = 99999, min = 1, exclude = 577;
var num = Math.floor(Math.random() * (max - min)) + min ;
while(num == exclude || num > max || num < min ) {
    var rand = Math.random() > .5 ? -20 : 20 ;
    num += Math.floor((Math.random() * (rand));
}   

答案 7 :(得分:-2)

从计算中排除数字:

&#13;
&#13;
function toggleRand() {
  // demonstration code only.
  // this algorithm does NOT produce random numbers.
  // return `0` - `576` , `578` - `n`  
  return [Math.floor((Math.random() * 576) + 1)
          ,Math.floor(Math.random() * (100000 - 578) + 1)
         ]
         // select "random" index 
         [Math.random() > .5 ? 0 : 1];
}

console.log(toggleRand());
&#13;
&#13;
&#13;

或者,使用String.prototype.replace()RegExp /^(577)$/匹配应从结果中排除的数字;使用[0-99]new Date().getTime()isNaN()

替换范围String.prototype.slice()中的其他随机数

&#13;
&#13;
console.log(
  +String(Math.floor(Math.random()*(578 - 575) + 575))
  .replace(/^(577)$/,String(isNaN("$1")&&new Date().getTime()).slice(-2))
);
&#13;
&#13;
&#13;

还可以使用String.prototype.match()来过滤结果:

&#13;
&#13;
console.log(
  +String(Math.floor(Math.random()*10)) 
  .replace(/^(5)$/,String(isNaN("$1")&&new Date().getTime()).match(/[^5]/g).slice(-1)[0])
);
&#13;
&#13;
&#13;