在不使用shuffle()函数的情况下,在PHP中随机化数组顺序的最佳方法是什么?

时间:2008-09-15 19:29:38

标签: php arrays random

我在求职面试中被问到这个问题。面试官和我不同意正确答案是什么。我想知道是否有人有这方面的任何数据。

更新:我应该提到严格禁止使用shuffle()...抱歉。

7 个答案:

答案 0 :(得分:4)

shuffle($arr);

:)

编辑:我应该澄清......我对最佳的定义不仅涉及算法效率,还涉及代码可读性和可维护性。使用标准库函数意味着保持更少的代码和更少的读取。除此之外,你可以与博士教授一起进行为期一年的关于最佳“真正随机”功能的辩论,所以有人会在随机问题上不同意你。

答案 1 :(得分:3)

这是我提出的解决方案:

function randomize_array_1($array_to_randomize) {
    $new_array = array();
    while (count($array_to_randomize) > 0) {
        $rand_num = rand(0, count($array_to_randomize)-1);
        $extracted = array_splice($array_to_randomize, $rand_num, 1);
        $new_array[] = $extracted[0];
    }
    return $new_array;
}

这是他的解决方案:

function randomize_array_2($array_to_randomize) {
    usort($array_to_randomize, "rand_sort");
    return $array_to_randomize;
}
function rand_sort($a, $b) {
    return rand(-1, 1);
}

我对这两种方法进行了大量试验(每次尝试1,000,000次),速度差异可以忽略不计。然而,在检查结果的实际随机性后,我对分布的差异感到惊讶。这是我的结果:

randomize_array_1:
    [2, 3, 1] => 166855
    [2, 1, 3] => 166692
    [1, 2, 3] => 166690
    [3, 1, 2] => 166396
    [3, 2, 1] => 166629
    [1, 3, 2] => 166738

randomize_array_2:
    [1, 3, 2] => 147781
    [3, 1, 2] => 73972
    [3, 2, 1] => 445004
    [1, 2, 3] => 259406
    [2, 3, 1] => 49222
    [2, 1, 3] => 24615

正如你所看到的,第一种方法提供了一种近乎完美的分布,表明它或多或少是真正随机的,而第二种方法是无处不在。

答案 2 :(得分:2)

您可以使用Fisher-Yates shuffle

答案 3 :(得分:1)

他可能会对大多数人在实施改组算法时犯下的一个相对常见的错误进行测试(实际上这也是几年前涉及在线扑克网站的controversy的中心)

改组的方式不正确:

for (i is 1 to n) Swap i with random position between 1 and n

正确的洗牌方式:

for (i is 1 to n) Swap i with random position between i and n

绘制出这些案例的概率分布图,很容易看出为什么第一个解决方案不正确。

答案 4 :(得分:0)

“正确”的方式非常模糊。排序数组的最佳(最快/最简单/最优雅)就是使用内置的shuffle()函数。

答案 5 :(得分:0)

PHP具有内置功能 - > shuffle()。我会说你应该做你喜欢的事情,但它很可能只是完全'随机'。

检查http://computer.howstuffworks.com/question697.htm,了解为什么非常非常难以从计算机中获得完整的随机性。

答案 6 :(得分:0)

简答:PHP的array_rand()功能

鉴于禁止使用shuffle函数,我会使用$keys = array_rand($myArray, count($myArray))以随机顺序从$myArray返回键的数组。从那里开始,应该很容易将它们重新组装成一个随机化的新数组。类似的东西:

$keys = array_rand($myArray, count($myArray));
$newArray = array();

foreach ($keys as $key) {
$newArray[$key] = $myArray[$key];
}