繁体   English   中英

JavaScript:我需要递归 function 来解决这个问题吗?

[英]JavaScript: Do I need a recursive function to solve this problem?

在这个小提琴http://jsfiddle.net/5L8Q8/28/中,如果单击黑色按钮,它会从数组中随机选择两个值(红色或蓝色)之一。 随机选择的值分配给ran 在我的实际应用程序中,该数组中将有 16 个元素。

如果你是粉红色的“再次播放”按钮,它会从同一个数组中选择一个随机元素,但我想确保它与上次选择的元素不同。

因此,当我再次单击playagain时,我将ran分配给lastran并将其与数组中的下一个随机选择的值进行比较,如果它们相同,则再次随机选择。 但是,我拥有它的方式并不能保证(在playagain完成后) ran是不同的。

我想我需要一个递归 function 注释 2 在下面的代码中,但是当我尝试创建它时,我一直在破坏我的代码。

你能评论下面代码中的 3 条评论吗?

请注意,我是一个相对新手,所以这段代码可能很糟糕......

$("#playagain").click(function(){
    lastran = ran; 


    ran = getRandom(myArray, true);

    if (ran === lastran) { 

        ran = getRandom(myArray, true); //1. do I need to return this?

           //2. want to test ran === lastran again.. How to set up recursive function?

    } else {

       return; //3.is this the right thing to do here?
    }  

});
while( (ran = getRandom(myArray, true)) === lastran)
    ;

是你想要的。 该声明

ran = getRandom(myArray, true)

不仅将ran设置为getRandom() ,而且返回ran的值。 (这是 JavaScript 中相当常见的习语,从 C 继承而来。)

所以你的完整代码可以是:

$("#playagain").click(function(){
    /*var */lastran = ran; 

    while( (ran = getRandom(myArray, true)) === lastran)
        ;

    // update UI here

});

您可以使用 while 循环代替 if。

while(ran == lastran)
{
  ran = getRandom(myArray, true);
}

它会继续尝试,直到获得不同的值。

每次运行后,只需从数组中删除该“键”并将 lastran 推到它的末尾。 然后更新的 getRandom function 可用于#button 和#playagain。 http://jsfiddle.net/ghostoy/5L8Q8/32/

function getRandom(array, getVal) {
    var key = Math.floor(Math.random() * array.length),
        value = array[key];

    if (lastran) {
        array.push(lastran);
    }

    array.splice(key, 1);
    lastran = value;

    if (getVal) {
        return value; 
    }
    return key; 
}

我认为您的方法不是解决此问题的最佳方法。 从理论上讲,您可以连续多次获得相同的数字,从而使其成为“慢”算法,并且您使它变得比需要的更复杂。

文本中的另一种方法:

- if no previous element has been picked pick a number between 0 and the number of elements in your array (16) otherwise pick a number between 0 and #elements-1 (15)
- if the chosen element is greater or equal to the last element picked add 1 to it 
- store this index number as the last picked element
- return the array[picked-element]'s value

您可以使getRandom本身递归:

function getRandom(array, getVal, lastRan) { 
    var key = Math.floor(Math.random() * array.length);
    if ((!getVal && key == lastRan) || (getVal && array[key] == lastRan))
        return getRandom(array, getVal, lastRan);
    return getVal ? array[key] : key;
}

调用它传递最后一个随机值:

getRandom(myArray, true, lastran)

它是这样工作的。 您始终将获取的最后一个随机值传递给getRandom 在第一个条件中,我们检查我们是否刚刚生成了该值的副本(使用键本身或其在数组中的对应值,取决于getVal是否为true )。 如果是这样,我们再次返回调用getRandom的结果,再次传递上次使用的随机数。 这可以根据需要多次发生。

当其中一个对getRandom的调用产生一个新数字时,第一个条件中的表达式将为假。 在这种情况下,我们返回想要的值(通过第二个return语句)并且所有对getRandom的递归调用都“展开”。 (请记住,我们在每一步都将每次调用的值返回给getRandom 。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM