Вернуть случайное число, но не 2 - PullRequest
5 голосов
/ 19 августа 2009

Почему это иногда возвращает 2?

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

Ответы [ 10 ]

26 голосов
/ 19 августа 2009

Ответ на ваш вопрос, как уже отмечали другие, заключается в том, что ваш код проваливается без возврата. Если 2 возвращается вызовом rand () как с первой попытки , так и со второй попытки (вероятность этого составляет 1/16), в результате вы получите 2 .

Но ваш подход к решению проблемы мог бы быть лучше.

И рекурсия, и зацикливание слишком сложны для этой проблемы. Это проблема mapping , а не проблема randomness . (Это напоминает некоторые распространенные проблемы интервьюирования со случайным кодированием, которые легче всего решить в цикле отклонения, но на самом деле это не проблема этого класса.)

Вам нужен один из трех результатов, а не четырех . (1, 3 и 4.) Это означает, что вы должны генерировать диапазон из трех случайных чисел, а не четырех. Вы можете переназначить с помощью массива или использовать if. Обе возможности показаны ниже. Дайте мне знать, если у меня неправильный синтаксис - мой 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, что является эквивалентным решением.

19 голосов
/ 19 августа 2009

Потому что вы не останавливаете функцию там. четвертая строка должна гласить:

return pickServer();
13 голосов
/ 19 августа 2009

Другой способ сделать это - использовать do … while:

function pickServer() {
    do {
        $varr = rand(1,4);
    } while ($varr == 2);
    return $varr;
}
10 голосов
/ 19 августа 2009

Что вы, вероятно, хотите, это

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;
}
2 голосов
/ 19 августа 2009
function pickServer(){
    $varr = rand(1,4);
    if($varr==2){
        return pickServer(); //leave here
    }
    return $varr;
}
2 голосов
/ 19 августа 2009

Потому что, когда значение равно 2, вы не возвращаете pickserver. И функция продолжает возвращать $ varr.

1 голос
/ 19 августа 2009

Я бы так примерно так:

function pickServer()
{
$servers = array(1,3,4);
return $servers[rand(1,count($servers))]; 
}
0 голосов
/ 22 декабря 2009

Вы можете удалить рекурсию и переназначить случайно выбранный 2. Просто уменьшите диапазон и отобразите начало диапазона (в данном случае 2) на 1.

function pickServer(){
    $varr = rand(2,4);
    if($varr==2){
        return 1;
    }
    return $varr;
}
0 голосов
/ 19 августа 2009

Вы забыли вернуть значение ...

function pickServer(){
$varr = rand(1,4);
if($varr==2){
    return pickServer();
}
return $varr;
}
0 голосов
/ 19 августа 2009

Он вызывает функцию рекурсивно, чтобы получить другой номер, который не равен 2, но ничего не делает с этим результатом.

Попробуйте изменить pickServer () на return pickServer () .

Еще лучше, написать функцию итеративно, чтобы она просто зацикливалась, пока возвращаемое значение не станет равным 2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...