4

我最近接到了一项任务,但我失败了。我通常不要求逻辑,但今天我不得不问。这是任务。

我不允许使用php的rand()函数。相反,我可以使用此功能。

function getRandom()
{
     return rand(1,5);
}

好的,我试过这个函数,但它一定会返回从 3 到 7 的值。

function getMoreRandom()
{
    $value = getRandom();
    return $value + 2;

}

现在我必须定义一个 php 函数,它可以返回范围为 1 到 7 的随机数。我该怎么做?

4

6 回答 6

5
function getMoreRandom()
{
    do {
        $temp = 5 * (getRandom() - 1) + getRandom();
    } while ($temp > 21);

    return $temp % 7 + 1;
}
于 2013-01-25T13:28:04.283 回答
4

flov 的回答是正确的:

function getMoreRandom()
{
    do {
        $temp = 5 * (getRandom() - 1) + getRandom();
    } while ($temp > 21);

    return $temp % 7 + 1;
}

测试它:

$aryResults = array_pad(array(),8,0);
foreach(range(0,100000) as $i) $aryResults[getMoreRandom()]++;
$intSum = array_sum($aryResults);
foreach($aryResults as $intValue => $intCount) printf("Value %d Count %d (%.2f)\n",$intValue,$intCount,$intCount/$intSum);

产生矩形分布

Value 0 Count 0 (0,00)
Value 1 Count 14328 (0,14)
Value 2 Count 14316 (0,14)
Value 3 Count 14185 (0,14)
Value 4 Count 14197 (0,14)
Value 5 Count 14322 (0,14)
Value 6 Count 14361 (0,14)
Value 7 Count 14292 (0,14)

抱歉,我没有对答案发表评论。显然我不能,因为我缺乏声誉(我是新来的)。

于 2013-01-25T13:51:18.747 回答
2

它不会是一个统一的分布(而且你没有指定它需要是)。

对于最简单的解决方案,您不需要进行缩放或循环,您可以将随机 1 到 5,然后添加随机 0 到 2;

function getMoreRandom()
{
    return getRandom() + getRandom() % 3;
}

快速测试看看分布是什么样的:

$results = array_fill(1, 7, 0);

for ($i = 0; $i < 1000000; $i++) {
    $results[rand(1,5) + rand(1,5) % 3]++;
}

var_dump($results);

如前所述,并非设计为均匀随机。

array(7) {
  [1]=>
  int(39550) // 4%
  [2]=>
  int(120277) // 12%
  [3]=>
  int(200098) // 20%
  [4]=>
  int(199700) // 20%
  [5]=>
  int(200195) // 20% 
  [6]=>
  int(160200) // 16%
  [7]=>
  int(79980) // 8%
}

稍微复杂一点,和@flovs 不同的方法(我不喜欢他的循环可能永远持续的方式 - 嘿,这就是随机性)

function getMoreRandom()
{
    for (
        $i = 0, $v = 0;
        $i < 7;
        $i++, $v += getRandom()
    );

    return $v % 7 + 1;
}

这会产生均匀分布

array(7) {
  [1]=>
  int(14397)
  [2]=>
  int(14218)
  [3]=>
  int(14425)
  [4]=>
  int(14116)
  [5]=>
  int(14387)
  [6]=>
  int(14256)
  [7]=>
  int(14201)
}
于 2013-01-25T14:22:16.273 回答
1

我的解决方案:

<?php

function getRandom()
{
     return rand(1,5);
}

$random_number = getRandom();
$random_number += time();

$random_number = ($random_number % 7) + 1;
于 2013-01-25T13:41:27.863 回答
0

只是为了提出一个很好的问题,我认为这可能更通用。这意味着我们可能不希望基于 rand(1,5) 的 1-7 而是 3-7 或 1-10 等。

该函数适用于数字 1-25,因为我正在使用另一种二维数组的解决方案。

function getMoreRand($start, $end){
        $restart = $start; //Save $start value, to restart if we reach the $end number 
        $parser = 0; //Count number elements in 2d array
        $result = 0; //Return the result based on rand(1,5)

        //Create a 2d array(), 5x5 to simulate the 1-5 random number selection from rand(1,5)
        for($row = 0; $row < 5; $row++){
            for($col = 0; $col < 5; $col++){
                $vars[$row][$col] = $start;

                //If the array elements left <= selected range left
                if((25-$parser) <= ($end-$start)){
                    $vars[$row][$col] = 0;
                }else{
                    if($start == $end){
                        $start = $restart;
                    }else{
                        $start++;
                    }
                }       
                $parser++;

            }//END OF FOR COL LOOP
        }//END OF FOR ROW LOOP


        while($result == 0){
            $i = getRandom(); //Choose 1-5
            $j = getRandom(); //Choose 1-5
            $result = $vars[$i-1][$j-1]; //Get number from 2d array, based on rand(1,5)
        }

        echo $result;
    }
于 2013-01-25T15:49:19.123 回答
-2
function getMoreRandom()
{
    $value = 0;
    for($i=1;$i<=5;$i++) $value += getRandom();
    return ($value % 7) + 1;
}
  • 首先,调用getRandom5 次,得到 5 到 25 的范围。这正好有 21 个值 - 7 的倍数。
  • 然后,找到 7 的模数。这会产生一个介于 0 和 6 之间的数字,每个数字都有 3 比 21 或 1 比 7 出现的机会。
  • 然后,为正确的范围添加一个。
于 2013-01-25T13:20:08.930 回答