Javascript 如何生成两个不同的随机数?
我需要生成两个不同的随机数,它们不能彼此相等,也不能等于第三个数。我试着用很多if来覆盖每一种可能性,但是,似乎我的算法技能不是很好 有人能帮我吗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
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;
};
})();