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

发布于 2024-11-19 00:23:48 字数 213 浏览 3 评论 0原文

似乎找不到这个问题的答案,假设我有这个:

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

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

Can't seem to find an answer to this, say I have this:

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

How do I make it so that random number doesn't repeat itself. For example if the random number is 2, I don't want 2 to come out again.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

原谅过去的我 2024-11-26 00:23:48

有多种方法可以实现这一目标。

方案一:
如果数字范围不大(假设小于 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);

There are a number of ways you could achieve this.

Solution A:
If the range of numbers isn't large (let's say less than 10), you could just keep track of the numbers you've already generated. Then if you generate a duplicate, discard it and generate another number.

Solution B:
Pre-generate the random numbers, store them into an array and then go through the array. You could accomplish this by taking the numbers 1,2,...,n and then shuffle them.

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

Solution C:
Keep track of the numbers available in an array. Randomly pick a number. Remove number from said array.

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);
笙痞 2024-11-26 00:23:48

您似乎想要一个从 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];
  }
}());


// Run 3 times
for (let i=0; i<3; i++) {
  console.log('run ' + i);
  for (let j=0; j<7; j++) {
    console.log(getRand());
  }
}

它将按随机顺序返回数字 0 到 6。当每个都被绘制一次后,它将重新开始。

You seem to want a non-repeating random number from 0 to 6, so similar to tskuzzy's answer:

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


// Run 3 times
for (let i=0; i<3; i++) {
  console.log('run ' + i);
  for (let j=0; j<7; j++) {
    console.log(getRand());
  }
}

It will return the numbers 0 to 6 in random order. When each has been drawn once, it will start again.

对岸观火 2024-11-26 00:23:48

你能尝试一下吗

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

could you try that,

setInterval(function() {
    m = Math.floor(Math.random()*7);
    $('.foo:nth-of-type(' + m + ')').fadeIn(300);
}, 300);
若水微香 2024-11-26 00:23:48

我喜欢尼尔的回答,尽管这是需要一些递归。这是用java编写的,你仍然会得到大概的想法。请注意,如果您提取的数字多于 MAX,您将遇到无限循环,我可以修复该问题,但为了清楚起见,将其保留原样。

编辑:看到尼尔添加了一个 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());
        }
    }
}

I like Neal's answer although this is begging for some recursion. Here it is in java, you'll still get the general idea. Note that you'll hit an infinite loop if you pull out more numbers than MAX, I could have fixed that but left it as is for clarity.

edit: saw neal added a while loop so that works great.

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());
        }
    }
}
前事休说 2024-11-26 00:23:48

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

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

结果集数字将包含您的所有索引而不重复。

更好的是,也许是这样的:

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

然后只需浏览这些项目,因为随机播放会将它们随机化,并一次将它们弹出一个。

Generally my approach is to make an array containing all of the possible values and to:

  1. Pick a random number <= the size of the array
  2. Remove the chosen element from the array
  3. Repeat steps 1-2 until the array is empty

The resulting set of numbers will contain all of your indices without repetition.

Even better, maybe something like this:

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

Then just go through the items because shuffle will have randomized them and pop them off one at a time.

孤千羽 2024-11-26 00:23:48

这是一个简单的修复,虽然有点初级:

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

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

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

这不是最优雅或技术最精湛的解决方案,但它确实有效:)

Here's a simple fix, if a little rudimentary:

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

If the next number is the same as the last simply minus 1 unless the number is 0 (zero) and set it to any other number within your set (I chose 7, the highest index).

I used this method within the cycle function because the only stipulation on selecting a number was that is musn't be the same as the last one.

Not the most elegant or technically gifted solution, but it works :)

爱*していゐ 2024-11-26 00:23:48

使用套装。它们在 ES6 中被引入到规范中。集合是一种表示唯一值集合的数据结构,因此它不能包含任何重复值。我需要 6 个随机的、不可重复的数字,范围从 1 到 49。我首先创建一个大约 30 位的较长集合(如果值重复,该集合将包含更少的元素),将集合转换为数组,然后将其前 6 个元素切片。简单易行。 Set.length 默认情况下未定义,它是无用的,这就是为什么如果您需要特定长度,将其转换为数组会更容易。

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

Use sets. They were introduced to the specification in ES6. A set is a data structure that represents a collection of unique values, so it cannot include any duplicate values. I needed 6 random, non-repeatable numbers ranging from 1-49. I started with creating a longer set with around 30 digits (if the values repeat the set will have less elements), converted the set to array and then sliced it's first 6 elements. Easy peasy. Set.length is by default undefined and it's useless that's why it's easier to convert it to an array if you need specific length.

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);
撩发小公举 2024-11-26 00:23:48

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

     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)

An easy way to generate a list of different numbers, no matter the size or number:

     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)

痕至 2024-11-26 00:23:48

我想补充一点——

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

这使用时间戳(每毫秒)来始终生成一个唯一的数字。

I would like to add--

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

This uses timestamp (every millisecond) to always generate a unique number.

带刺的爱情 2024-11-26 00:23:48

最小到最大之间的随机数

function getRandomNumbersWithoutRepeats(min, max) {   
    const numbers = [];   
    for (let i = min; i <= max; i++) { 
        numbers.push(i);   
    }  
    for (let i = numbers.length - 1; i > 0; i--) {   
        const j = Math.floor(Math.random() * (i + 1));  
        [numbers[i], numbers[j]] = [numbers[j], numbers[i]];  
    }
    return numbers;  
}   

const randomNumbers = getRandomNumbersWithoutRepeats(1, 10);
console.log(randomNumbers);

Random Number Between Min to Max

function getRandomNumbersWithoutRepeats(min, max) {   
    const numbers = [];   
    for (let i = min; i <= max; i++) { 
        numbers.push(i);   
    }  
    for (let i = numbers.length - 1; i > 0; i--) {   
        const j = Math.floor(Math.random() * (i + 1));  
        [numbers[i], numbers[j]] = [numbers[j], numbers[i]];  
    }
    return numbers;  
}   

const randomNumbers = getRandomNumbersWithoutRepeats(1, 10);
console.log(randomNumbers);

滿滿的愛 2024-11-26 00:23:48

你可以做到这一点。拥有您使用过的密钥的公共数组,并使用此函数检查它们:(

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

    return false;
}

函数来自: javascript function inArray< /a>)

所以你可以做的是:

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

这段代码在获取所有七个数字后会卡住,所以你需要确保它在找到所有数字后存在。

you can do this. Have a public array of keys that you have used and check against them with this function:

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

    return false;
}

(function from: javascript function inArray)

So what you can do is:

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

This code will get stuck after getting all seven numbers so you need to make sure it exists after it fins them all.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文