如何有效地随机选择数组项而不重复? [英] How to efficiently randomly select array item without repeats?

查看:166
本文介绍了如何有效地随机选择数组项而不重复?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这个问题存在很多问题,但我无法找到与我的具体效率问题相关的答案。

I'm aware that this question is around in many guises but I have not been able to find an answer relating to my specific issue of efficiency.

我有下面的代码工作得很好。

I have the below code that works just fine.

我有一个10个项目的数组,我随机选择一个项目(按下回车键)。代码保留了最近5个选项的数组,这些选择不能随机选择(以避免随着时间的推移重复过多)。

I have a 10 item array from which I randomly select an item (on enter key press). The code keeps an array of the 5 most recent choices which cannot be randomly selected (to avoid too much repetition over time).

如果chooseName()函数最初选择了在最近的5中使用过的名称只是断开并再次调用自身,重复直到找到唯一名称。

If the chooseName() function initially selects a name that has been used in the recent 5 goes it simply breaks and calls itself again, repeating until it finds a "unique" name.

我有两个问题:


  1. 说这是递归函数是否正确?

  1. Is it correct to say this is a "recursive function"?

我担心理论上这可能会在找到唯一名称之前保持循环很长时间 - 是否有更有效的方法来执行此操作?

I am worried that theoretically this could keep looping for a long time before finding a unique name - is there a more efficient way to do this?

感谢您的帮助。

    var a = ["Roger", "Russell", "Clyde", "Egbert", "Clare", "Bobbie", "Simon", "Elizabeth", "Ted", "Caroline"];
    var b = [];

    var chooseName = function () {
    var unique = true;
    b.length = 5;
    num = Math.floor(Math.random() * a.length);
    name = a[num];    
        for (i = 0; i < a.length; i++) {
        if (b[i] == name) {
            chooseName();
            unique = false;
            break;
            }
        }
        if (unique == true) {
        alert(name);
        b.unshift(name);
        }
    }


    window.addEventListener("keypress", function (e) {
        var keycode = e.keyCode;
        if (keycode == 13) {
        chooseName();
        }
    }, false);


推荐答案

每当选择一个项目时,将其移到后面的数组并从原始数组的切片中随机选择 array.slice(0,-5)

Whenever an item is selected, move it to the back of the array and randomly select from a slice of the original array array.slice(0, -5).

var a = ["Roger", "Russell", "Clyde", "Egbert", "Clare", "Bobbie", "Simon", "Elizabeth", "Ted", "Caroline"];

var chooseName = function () {
    var unique = true;
    num = Math.floor(Math.random() * a.length - 5);
    name = a.splice(num,1);
    a.push(name);
}


window.addEventListener("keypress", function (e) {
    var keycode = e.keyCode;
    if (keycode == 13) {
        chooseName();
    }
}, false);

编辑:这也有副作用,即不给出任何变量发生在列表上的不公平缺点是在前N个呼叫中不会考虑它们。如果这对您来说是个问题,可以尝试在某处保持一个静态变量来跟踪要使用的切片的大小,并在B处最大化(在本例中为5)。
例如

This also has the side-effect of not giving whichever variables happen to tail the list the unfair disadvantage that they won't be considered in the first N calls. If that's a problem for you, maybe try hold a static variable somewhere to keep track of the size of the slice to use and max it out at B (in this case, 5). e.g.

var a = ["Roger", "Russell", "Clyde", "Egbert", "Clare", "Bobbie", "Simon", "Elizabeth", "Ted", "Caroline"];
B = 5; //max size of 'cache'
N = 0;

var chooseName = function () {
    var unique = true;
    num = Math.floor(Math.random() * a.length - N);
    N = Math.min(N + 1, B);
    name = a.splice(num,1);
    a.push(name);
}

这篇关于如何有效地随机选择数组项而不重复?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆