不重复前一个数字的数学随机数

math random number without repeating a previous number

本文关键字:数字 一个 随机数      更新时间:2023-09-26

似乎找不到答案,说我有这个:

setInterval(function() {
    m = Math.floor(Math.random()*7);
    $('.foo:nth-of-type('+m+')').fadeIn(300);
}, 300);

如何使随机数不重复呢?例如,如果随机数是2,我不希望再次出现2。

有很多方法可以做到这一点。

解决方案一:如果数字的范围不大(假设小于10),您可以只跟踪已经生成的数字。然后,如果生成了一个重复的数字,则丢弃它并生成另一个数字。

解决方案B:预生成随机数,将它们存储到数组中,然后遍历数组。您可以通过取数字1,2,...,n,然后对它们进行洗牌来完成此操作。

shuffle = function(o) {
    for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
    return o;
};
var randorder = shuffle([0,1,2,3,4,5,6]);
var index = 0;
setInterval(function() {
    $('.foo:nth-of-type('+(randorder[index++])+')').fadeIn(300);
}, 300);

解决方案C:跟踪数组中可用的数字。随机选一个数字。从数组中删除数字。

var randnums = [0,1,2,3,4,5,6];
setInterval(function() {
    var m = Math.floor(Math.random()*randnums.length);
    $('.foo:nth-of-type('+(randnums[m])+')').fadeIn(300);
    randnums = randnums.splice(m,1);
}, 300);

您似乎想要一个从0到6的非重复随机数,所以类似于tskuzzy的答案:

var getRand = (function() {
    var nums = [0,1,2,3,4,5,6];
    var current = [];
    function rand(n) {
        return (Math.random() * n)|0;
    }
    return function() {
      if (!current.length) current = nums.slice();
      return current.splice(rand(current.length), 1);
    }
}());

它将以随机顺序返回数字0到6。

你可以试试吗,

setInterval(function() {
    m = Math.floor(Math.random()*7);
    $('.foo:nth-of-type(' + m + ')').fadeIn(300);
}, 300);

我喜欢Neal的回答,尽管这需要一些递归。这是用java编写的,您仍然可以得到大致的概念。请注意,如果您取出的数字超过MAX,您将遇到无限循环,我本可以修复这个问题,但为了清晰起见保留它。

edit: saw neal添加了一个while循环,所以效果很好。

public class RandCheck {
    private List<Integer> numbers;
    private Random rand;
    private int MAX = 100;
    public RandCheck(){
        numbers = new ArrayList<Integer>();
        rand = new Random();
    }
    public int getRandomNum(){
        return getRandomNumRecursive(getRand());
    }
    private int getRandomNumRecursive(int num){
        if(numbers.contains(num)){
            return getRandomNumRecursive(getRand());
        } else {
            return num;
        }
    }
    private int getRand(){
        return rand.nextInt(MAX);
    }
    public static void main(String[] args){
        RandCheck randCheck = new RandCheck();
        for(int i = 0; i < 100; i++){
            System.out.println(randCheck.getRandomNum());
        }
    }
}

一般来说,我的方法是创建一个包含所有可能值的数组,并:

  1. 选择一个随机数<=数组的大小
  2. 从数组中移除所选元素
  3. 重复步骤1-2,直到数组为空

生成的数字集将包含所有索引而不重复。

更好,也许像这样:

var numArray = [0,1,2,3,4,5,6];
numArray.shuffle();

然后遍历这些项因为shuffle会随机化它们,每次取出一个

这里有一个简单的修复,如果有点基本:

if(nextNum == lastNum){
    if (nextNum == 0){nextNum = 7;} 
    else {nextNum = nextNum-1;}
}

如果下一个数字与上一个数字相同,则简单地减去1,除非该数字为0(零),并将其设置为集合中的任何其他数字(我选择7,最高索引)。

我在循环函数中使用了这种方法,因为选择一个数字的唯一规定是它不能与上一个相同。

不是最优雅或技术天赋的解决方案,但它有效:)

使用集合。它们是在ES6中引入规范的。set是表示唯一值集合的数据结构,因此不能包含任何重复值。我需要6个随机的,不可重复的数字,范围从1到49。我开始创建一个大约30个数字的更长的集合(如果值重复,集合将有更少的元素),将集合转换为数组,然后切片它的前6个元素。容易peasy。。长度默认情况下未定义,这是无用的,这就是为什么如果你需要特定的长度,将其转换为数组更容易。

let randomSet = new Set();
for (let index = 0; index < 30; index++) {
        randomSet.add(Math.floor(Math.random() * 49) + 1) 
    };
let randomSetToArray = Array.from(randomSet).slice(0,6);
console.log(randomSet);
console.log(randomSetToArray);

生成不同数字列表的简单方法,无论大小或数字:

     function randomNumber(max) {
          return Math.floor(Math.random() * max + 1);
        }
        
        const list = []
        while(list.length < 10 ){
            let nbr = randomNumber(500)
            if(!list.find(el => el === nbr)) list.push(nbr) 
        }
        
        console.log("list",list)

我想添加——

var RecordKeeper = {};
SRandom = function () {
    currTimeStamp = new Date().getTime();
    if (RecordKeeper.hasOwnProperty(currTimeStamp)) {
        RecordKeeper[currTimeStamp] = RecordKeeper[currTimeStamp] + 1;
        return currTimeStamp.toString() + RecordKeeper[currTimeStamp];
    }
    else {
        RecordKeeper[currTimeStamp] = 1;
        return currTimeStamp.toString() + RecordKeeper[currTimeStamp];
    }
}

使用时间戳(每毫秒)总是生成一个唯一的数字。

你可以这样做。拥有一个您使用过的键的公共数组,并使用以下函数对它们进行检查:

function in_array(needle, haystack)
{
    for(var key in haystack)
    {
        if(needle === haystack[key])
        {
            return true;
        }
    }
    return false;
}

(function from: javascript function)

那么你可以做的是:

var done = [];
setInterval(function() {
    var m = null;
    while(m == null || in_array(m, done)){
       m = Math.floor(Math.random()*7);
    }
    done.push(m);
    $('.foo:nth-of-type('+m+')').fadeIn(300);
}, 300);

此代码在获得所有七个数字后会卡住,因此您需要确保它在所有数字之后存在。

相关文章: