Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 返回随机数,但不是2_Php_Recursion_Random - Fatal编程技术网

Php 返回随机数,但不是2

Php 返回随机数,但不是2,php,recursion,random,Php,Recursion,Random,为什么有时返回2 function pickServer(){ $varr = rand(1,4); if($varr==2){ pickServer(); } return $varr; } 因为你没有停止那里的函数。第四行应改为: return pickServer(); 因为当值为2时,不返回pickserver。函数继续返回$varr。它递归调用函数以获取另一个不是2的数字,但对该结果不做任何处理 尝试将pickServer()更改为返

为什么有时返回2

function pickServer(){
    $varr = rand(1,4);
    if($varr==2){
        pickServer();
    }
    return $varr;
}

因为你没有停止那里的函数。第四行应改为:

return pickServer();

因为当值为2时,不返回pickserver。函数继续返回$varr。

它递归调用函数以获取另一个不是2的数字,但对该结果不做任何处理

尝试将pickServer()更改为返回pickServer()


更好的方法是,迭代编写函数,使其循环直到返回的值不是2。

您可能需要的是

function pickServer(){
    $varr = rand(1,4);
    if($varr==2){
        return pickServer(); //leave here
    }
    return $varr;
}
function pickServer(){
  $varr = rand(1,4);
  if($varr==2){
    $varr = pickServer();
  }
  return $varr;
}
--但是请注意,不能保证这不会进入太长的递归。也许你更应该这样做:

function pickServer(){
  $varr = rand(1,3);
  if($varr > 1){
    $varr = $varr + 1;
  }
  return $varr;
}
function pickServer()
{
$servers = array(1,3,4);
return $servers[rand(1,count($servers))]; 
}

您忘记返回值了

function pickServer(){
$varr = rand(1,4);
if($varr==2){
    return pickServer();
}
return $varr;
}

另一种方法是使用
do…while

function pickServer() {
    do {
        $varr = rand(1,4);
    } while ($varr == 2);
    return $varr;
}

正如其他人所指出的,您的问题的答案是,您的代码没有返回就被破解了。如果在第一次尝试和第二次尝试时调用rand()都返回了
2
(发生这种情况的概率为1/16),那么您将得到
2

但你解决问题的方法可能会更好

对于这个问题,递归和循环都很糟糕。这是一个映射问题,而不是随机性问题。(它类似于一些常见的随机编码面试问题,这些问题在拒绝循环中最容易处理,但它实际上不是这一类的问题。)

你想要三个结果中的一个,而不是四个。(1、3和4。)这意味着您应该生成三个随机数的范围,而不是四个。您可以使用数组重新映射,或者在的情况下使用
。这两种可能性如下所示。如果语法错误,请告诉我——我的PHPfu今天早上很弱

/* array remapping */
function pickServer() {
    $remap = array(1, 3, 4);
    return $remap[rand(1,3)];
}

/* if remapping */
function pickServer() {
    $server = rand(1,3);
    if ($server==2) {
        $server=4;
    }
    return $server;
}

我以前没有注意到,但巴尔法预料到了我的答案。在他的第二个示例中,他用
if
重新映射。他没有将2重新映射为4,而是将1添加到1以上的任何答案中,这是一个等效的解决方案。

我想这样做:

function pickServer(){
  $varr = rand(1,3);
  if($varr > 1){
    $varr = $varr + 1;
  }
  return $varr;
}
function pickServer()
{
$servers = array(1,3,4);
return $servers[rand(1,count($servers))]; 
}

您可以删除递归并重新映射随机选择的2。只需减小范围并将范围的开始(在本例中为2)映射为1



谢谢大家,都对了,但我只选了一个。:)实际上,他们中的大多数人都忽略了真正的问题(包括公认的答案)。不要使用递归作为转到。在$var=rand(1,4)调用周围放置一个循环,直到它返回一个值=2、不要在此方法内再次调用pickServer。想想孩子们!想想你的堆栈框架!如果你运行这段代码,并达到2的连胜,理论上你可以创建StackOverflow条件,我不是说一个问答维基网站。不要循环。您的随机生成范围太大—您看不到它,因为要排除的数字在该范围内。如果是在开始或结束,你不会循环,所以为什么只是因为它是在中间循环?重新映射。+!谢谢你。这就是我刚才写的。这些解决方案中的许多可能在技术上可行,但具有不确定和递归(包括公认的答案)的不良副作用。这是一个危险的组合,它会变成一个虚幻的错误,会使你的系统随机崩溃。。。偶尔。。。没有明显的原因。@Nosredna-我同意。技术上最正确的答案是将随机空间重新映射到不包含“2”的空间。然后您的方法将在O(1)时间内执行。在方法内部循环是一种快速、实用的方法,可以解决基本问题,但从学术角度来看,它不是最佳解决方案。但是我同意你的观点,方法不应该是不确定的,也不应该是递归的。可以说更好,因为大多数语言都不优化尾部递归,这一点也不比递归的更清楚。最后,有人有点理智地指出,将递归作为一种后置操作是疯狂的+1我认为对于手头的问题,递归和循环都是疯狂的。:-)第二个最好的答案,但远远落后于Nosrednas。语法在我看来是正确的。做得好。这应该是选择的答案。一个真正的随机RNG可能永远返回2。至少这不会陷入循环。我想你会发现一个真正的RNG总是返回4:+1。最初的功能和公认的答案在刑事上都是无效的。无论在你的范围内有多少个“洞”,你总是可以把它概括为一个映射问题。这仍然是递归的,并且有潜在的危险。请参阅原始问题的评论讨论。这对于回答“为什么”很有用。但正如Robert指出的那样,这会导致一个可怕的解决方案。它与Nosredna的解决方案一样有效,但需要考虑一下。您的第二段代码很好地处理了这个问题。我关心的只是它的破译有点棘手。事实上,当我第一次通读答案时,我错过了它,正是因为它不明显。我很抱歉错过了。如果我第一次注意到的话,我会在我的回答中相信你。更新:我在我的回答中给了你道具。我记不清足够的PHP,但出于好奇,你能做$varr+=$var>1;在PHP中?(我知道它看起来很糟糕。)我以为在PHP中使用零或两个参数调用rand()。rand返回整数。我想这就是你想要的。。。返回$servers[rand(1,count($servers))];