php阵列生成挑战

时间:2010-07-18 08:13:12

标签: php arrays multidimensional-array

我需要随机生成一个二维n×n数组。在此示例中,n = 10.数组应具有此结构。一个例子:

$igra[]=array(0,1,2,3,4,5,6,7,8,9);
$igra[]=array(6,9,1,5,0,2,7,3,4,8);
$igra[]=array(2,5....................
$igra[]=array(1,7.....................
$igra[]=array(5,4...................
$igra[]=array(4,2...................
$igra[]=array(9,0.....................
$igra[]=array(8,3.....................
$igra[]=array(7,6....................
$igra[]=array(3,8....................

其中

`$igra[x][z]!=$igra[y][z]`   (x={0,9},y={0,9});

如你所见它就像一个数字矩阵,它的每一行和列也由数字0-9组成,并且每行或每列中从不有一个数字。 如何生成这样的数组,并且每次都是随机的。

3 个答案:

答案 0 :(得分:7)

好的,所以这是我的版本:

$n = 10;

$v1 = range(0, $n-1);
$v2 = range(0, $n-1);
shuffle($v1);
shuffle($v2);

foreach ($v1 as $x => $value)
    foreach ($v2 as $y)
        $array[$y][$x] = $value++ % $n;

这应该是一个非常快速的算法,因为它只涉及生成两个随机数组,并且根本不涉及任何交换。它也应该是随机的,但我不能证明它。 (至少我不知道如何证明这样的事情。)

这是一个非常简单的算法的优化版本:

首先以这种方式创建一个非随机矩阵(想象我们只需要5 * 5,而不是10 * 10):

0 1 2 3 4
1 2 3 4 0
2 3 4 0 1
3 4 0 1 2
4 0 1 2 3

在这个矩阵中,我们现在随机交换列。由于我们不更改列本身,您的规则仍然遵守。然后我们随机交换行。

现在,正如您所看到的,上述算法不会交换任何内容,也不会生成上述矩阵。那是因为它生成cols和行以提前交换($v1$v2),然后直接写入结果数组中的正确位置。

编辑:刚做了一些基准测试:对于$n = 500,需要0.3秒。

Edit2:用foreach循环替换for循环后,只需0.2秒。

答案 1 :(得分:2)

这就是我所做的。制作了一个非随机的有效矩阵(2d数组)。所以从开始,第0行是0-9,第1行是1-0(即:1,2,3 ...... 8,9,0),第2行是2-1(2,3 ... 9, 0,1)......第8行是8-7 ......等。然后将该数组随机化以随机化行并执行简单的列交换以使列随机化。应该准确回到你想要的。试试这个:

<?php
//simple function to show the matrix in a table.
function show($matrix){
    echo '<table border=1 cellspacing=0 cellpadding=5 style="float: left; margin-right:20px;">';
    foreach($matrix as $m){
        echo '<tr>';
        foreach($m as $n){
            echo '<td>'.$n.'</td>';
        }
        echo '</tr>';
    }
    echo '</table>';
}

//empty array to store the matrix
$matrix = array();

//this is what keeps the current number to put into matrix
$cnt = 0;

//create the simple matrix
for($i=0;$i<=9;$i++){
    for($j=0;$j<=9;$j++){
        $matrix[$i][$j] = $cnt % 10;
        $cnt++;
    }
    $cnt++;
}

//display valid simple matrix
show($matrix);

//shuffle the rows in matrix to make it random
shuffle($matrix);

//display matrix with shuffled rows.
show($matrix);

//swap the columns in matrix to make it more random.
for($i=0;$i<=9;$i++){
    //pick a random column
    $r = mt_rand(0, 9);
    //now loop through each row and swap the columns $i with $r
    for($j=0;$j<=9;$j++){
        //store the old column value in another var
        $old = $matrix[$j][$i];
        //swap the column on this row with the random one
        $matrix[$j][$i] = $matrix[$j][$r];
        $matrix[$j][$r] = $old;
    }
}

//display final matrix with random rows and cols
show($matrix);
?>

在我的解决方案中,通过不生成随机数组并检查它是否已经存在,它应该运行得更快(特别是如果数组超过0-9)。当你到达最后一行时,只有一种可能的数字组合。您将生成随机数组,试图找到一个答案。它与从1到10中选择一个数字并产生一个随机数直到它击中你选择的数字几乎相同。它可能是第一次尝试,但是你可以再次选择1000个随机数字,但永远不会得到你想要的那个。

答案 2 :(得分:0)

嗯..我看到你已经有了一些好的答案,但这是我的版本:

$n = 10;

$seed_row = range(0, $n - 1);
shuffle($seed_row);

$result = array();
for($x = 0; $x < $n; $x++)
{
    $tmp_ar = array();
    $rnd_start = $seed_row[$x];
    for($y = $rnd_start; $y < ($n + $rnd_start); $y++)
    {
        if($y >= $n) $idx = $y - $n;
        else $idx = $y;
        $tmp_ar[] = $seed_row[$idx];
    }
    $result[] = $tmp_ar;
}

for($x = 0; $x < $n; $x++)
{
    echo implode(', ', $result[$x]) . "<br/>\n";
}

示例输出:

4, 3, 0, 2, 6, 5, 7, 1, 8, 9
0, 2, 6, 5, 7, 1, 8, 9, 4, 3
7, 1, 8, 9, 4, 3, 0, 2, 6, 5
2, 6, 5, 7, 1, 8, 9, 4, 3, 0
6, 5, 7, 1, 8, 9, 4, 3, 0, 2
9, 4, 3, 0, 2, 6, 5, 7, 1, 8
8, 9, 4, 3, 0, 2, 6, 5, 7, 1
5, 7, 1, 8, 9, 4, 3, 0, 2, 6
1, 8, 9, 4, 3, 0, 2, 6, 5, 7
3, 0, 2, 6, 5, 7, 1, 8, 9, 4

它创建一个随机随机数组作为起点 然后它遍历种子数组,将每个元素作为自身的起点,以创建新的基础。