Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何生成两个不同的随机数?_Javascript_Algorithm_Random - Fatal编程技术网

Javascript 如何生成两个不同的随机数?

Javascript 如何生成两个不同的随机数?,javascript,algorithm,random,Javascript,Algorithm,Random,我需要生成两个不同的随机数,它们不能彼此相等,也不能等于第三个数。我试着用很多if来覆盖每一种可能性,但是,似乎我的算法技能不是很好 有人能帮我吗 var numberOne = Math.floor(Math.random() * 4); var numberTwo = Math.floor(Math.random() * 4); var numberThree = 3; // This number will not always be 3 if((numberOne == numberT

我需要生成两个不同的随机数,它们不能彼此相等,也不能等于第三个数。我试着用很多if来覆盖每一种可能性,但是,似乎我的算法技能不是很好

有人能帮我吗

var numberOne = Math.floor(Math.random() * 4);
var numberTwo = Math.floor(Math.random() * 4);
var numberThree = 3; // This number will not always be 3

if((numberOne == numberThree) && (numberOne + 1 < 3)) {
    numberOne++;
} else if ((numberOne == numberThree) && (numberOne + 1 == 3)) {
    numberOne = 0;
}

if ((numberOne == numberTwo) && (numberOne+1 < 3)) {
    if (numberOne+1 < 3) {
        numberOne++;
    } else if(numberThree != 0) {
        numberOne = 0;
    }
}
我的思路对吗?
注意:生成的数字需要介于0和3之间。提前感谢。

通常,在伪代码中,我会:

var nbr1 = random()
var nbr2 = random()
while (nbr1 == nbr2) {
    nbr2 = random();
}
这样你会得到两个不同的随机数。
通过附加条件,您可以使它们与另一(第三)个数字不同。

您可以在运行
的同时运行
循环,直到所有数字都不同

// All numbers are equal
var numberOne = 3; 
var numberTwo = 3; 
var numberThree = 3; 

// run this loop until numberOne is different than numberThree
do {
    numberOne = Math.floor(Math.random() * 4);
} while(numberOne === numberThree);

// run this loop until numberTwo is different than numberThree and numberOne
do {
    numberTwo = Math.floor(Math.random() * 4);
} while(numberTwo === numberThree || numberTwo === numberOne);
下面是基于@jfriend00建议的JSFIDLE,其中包含上述代码


这是原始的工作演示:

我不确定您想做什么(或者实际上,为什么您的代码对我的理解如此复杂)。这可能不是最优化的代码,但下面是我的尝试:

var n3 = 3;
var n2 = Math.floor(Math.random() * 4);
var n1 = Math.floor(Math.random() * 4);

while(n1 == n3)
{
    n1 = Math.floor(Math.random() * 4);
}
while (n2 == n1 || n2 == n3)
{
    n2 = Math.floor(Math.random() * 4);
}

编辑:该死,太晚了^ ^

您可以创建一个随机可能性数组,然后在使用时从该数组中删除项目,从数组中剩余的值中选择未来的随机数。这避免了试图查找与以前的项不匹配的值的循环

function makeRandoms(notThis) {
    var randoms = [0,1,2,3];

    // faster way to remove an array item when you don't care about array order
    function removeArrayItem(i) {
        var val = randoms.pop();
        if (i < randoms.length) {
            randoms[i] = val;
        }
    }

    function makeRandom() {
        var rand = randoms[Math.floor(Math.random() * randoms.length)];
        removeArrayItem(rand);
        return rand;
    }

    // remove the notThis item from the array
    if (notThis < randoms.length) {
        removeArrayItem(notThis);
    }

    return {r1: makeRandom(), r2: makeRandom()};
}
函数makeRandoms(不是这个){
var随机数=[0,1,2,3];
//当您不关心数组顺序时,删除数组项的更快方法
函数removeArrayItem(i){
var val=randoms.pop();
如果(i<随机长度){
随机数[i]=val;
}
}
函数makeRandom(){
var rand=randoms[Math.floor(Math.random()*randoms.length)];
removeArrayItem(兰德);
返回兰特;
}
//从数组中删除notThis项
if(notThis
工作演示:


仅供参考,当你要求随机选择一个范围内的大多数数字时,这种技术通常比循环更有效,直到你得到新的东西,因为这只是从随机集中消除了以前使用过的数字,所以它不必反复猜测,直到得到一个未使用的值。

此版本将和您一样随机调用的次数,但有点简单,没有偏见。在你的版本中,numberOne变为0的几率为2/4,变为1和2的几率为1/4。在我的版本中,numberOne最终为0、1或2的几率是相等的

这是前面提到的数组洗牌版本deceze的一个特例,但只适用于只有两个数字的情况

var n = 4; //to get two random numbers between 0 and 3
var n3 = 2; //for example
var n1 = Math.floor(Math.random(n-1));
var n2 = Math.floor(Math.random(n-2));
if(n1 >= n3) {
    n1++;
    if(n2 >= n3)
        n2++;
    if(n2 >= n1)
        n2++;
} else {
    if(n2 >= n1)
        n2++;
    if(n2 >= n3)
        n2++;
}
您需要首先将
n2
n1
n3
中的最小值进行比较,以确保不存在相等值:

假设
n1=1
n3=2
。如果您得到
n2=1
并首先将其与
n3
进行比较,则在第一步中不会增加
n2
。在第二步中,您将增加它,因为
n2>=n1
。最后,
n2=2=n3


此算法保证有一个统一的分布,您只需调用两次
Math.random()

请注意,对
Math.random()
的背靠背调用会触发所示的错误,因此通过调用下面的
safeRand()
来修改任何其他答案:

function safeRand() {
  Math.random();
  return Math.random();
}
这仍然不理想,但会显著降低相关性,因为每增加一次对
Math.random()
的丢弃调用都会降低相关性。

var rangeTo=4;
var rangeTo = 4;
var uniqueID = (function () {
    var id, cache = [];
    return function () {
        id = Math.floor((Math.random() * (new Date).getTime()) % rangeTo);
        var cacheLength = cache.length;
        if (cacheLength === rangeTo) {
            throw new Error("max random error");
        };
        var i = 0
        while (i < cacheLength) {
            if (cache[i] === id) {
                i = 0;
                id = Math.floor((Math.random() * (new Date).getTime()) % rangeTo);
            }
            else {
                i++;
            }
        }
        cache.push(id);
        return id;
    };
})();
var uniqueID=(函数(){ 变量id,缓存=[]; 返回函数(){ id=Math.floor((Math.random()*(新日期).getTime())%rangeTo); var cacheLength=cache.length; 如果(cacheLength==rangeTo){ 抛出新错误(“最大随机错误”); }; 变量i=0 while(i
ES 6版本:

这基本上是一个如上所述的函数,但使用的是
箭头函数
扩展运算符

const uniqueRandom=(…compareNumbers)=>{
让我们数一数;
做{
uniqueNumber=Math.floor(Math.random()*4);
}while(compareNumbers.includes(uniqueNumber));
返回唯一编号;
};
常量numberOne=uniqueRandom();
const numberTwo=uniqueRandom(numberOne);
常数numberThree=uniqueRandom(numberOne,numberTwo);

日志(numberOne、numberTwo、numbertree)该数字应在什么范围内?如果它相对较小:用该范围内的所有数字填充一个数组,将其洗牌,取前两个。@deceze,这真是个好主意!Thanksbtw,确保使用真正的洗牌算法,如knuth洗牌。不要使用“随机排序作为比较”算法,因为这会导致有偏差的结果。这是为什么?(从统计学的角度)随机性需要有多好?忘掉计算机吧,想想。假设您有两个骰子,要求您输入两个介于1和6之间的随机数,但不允许它们彼此相等或等于数字4。你会怎么做?
floor
random
在Javascript中并不存在。它们是
Math
对象的一部分。最初,为了保持简单,我省略了数学,但在第二个问题上,我认为保存那些额外的字符真的不值得。@herby:我认为现在应该修复它,但看起来与保持原始的版本不同:)你真的应该把它弄干一些。为什么不至少使用一个
do{}while()
循环而不是普通的
while()
并删除
Math.floor(Math.random()*4)的四个副本中的两个呢
function safeRand() {
  Math.random();
  return Math.random();
}
var rangeTo = 4;
var uniqueID = (function () {
    var id, cache = [];
    return function () {
        id = Math.floor((Math.random() * (new Date).getTime()) % rangeTo);
        var cacheLength = cache.length;
        if (cacheLength === rangeTo) {
            throw new Error("max random error");
        };
        var i = 0
        while (i < cacheLength) {
            if (cache[i] === id) {
                i = 0;
                id = Math.floor((Math.random() * (new Date).getTime()) % rangeTo);
            }
            else {
                i++;
            }
        }
        cache.push(id);
        return id;
    };
})();