具有条件的数组排列

时间:2013-03-05 22:08:49

标签: php arrays permutation

这一定很简单,但是我的大脑在一天结束时就被炒了..请帮忙:

<?php

    $arr = array(
        array(1, 2, 3),
        array(10, 20, 30),
        array(100, 200, 300),
    );

?>

我需要内部数组的所有可能的permeations,唯一的例外是每个内部数组的每个元素每个排列只能使用一次。 E.g:

GOOD:

1-10-100
1-100-10
200-1-10

BAD:

1-2-3
30-20-200

可以更改原始布局。

3 个答案:

答案 0 :(得分:2)

这适用于任意数量的数组:

<?php

$arr = array(
    array(1, 2, 3),
    array(10, 20, 30),
    array(100, 200, 300),
    array(1000, 2000, 3000)
);

function permute($a, $b) {
    $perms = array();
    foreach($a as $va) {
        foreach($b as $vb) {
            $perms[] = sprintf('%s-%s', $va, $vb);
        }
    }
    return $perms;
}

$i=2;
$perms = permute($arr[0], $arr[1]);
while($i<count($arr)) {
    $perms = permute($perms, $arr[$i++]);
}

print_r($perms);

答案 1 :(得分:1)

这适用于任意数量的数组:

<?php
$arr = array(
    array(1, 2, 3),
    array(10, 20, 30),
    array(100, 200, 300),
);
print_r(foo(array(), $arr));

function foo($arr1 = array(), $arr2 = array()) {
    $perm_arr = array();

    // case 1: empty array vs outer array
    // eg: array() vs array(array(1, 2, 3), array(10, 20, 30), array(100, 200, 300))
    // recursively reduce the size of outer array via case 2
    if(empty($arr1) && (isset($arr2[0]) && is_array($arr2[0]))) {
        $arr_top = array();
        $arr_bot = $arr2;

        // get possible arrangements for further reduction
        // eg:
        // array(1, 2, 3) vs array(array(10, 20, 30), array(100, 200, 300)),
        // array(10, 20, 30) vs array(array(1, 2, 3), array(100, 200, 300)),
        // array(100, 200, 300) vs array(array(1, 2, 3), array(10, 20, 30)),
        // ...
        while(0 < count($arr_bot)) {
            $arr = array_shift($arr_bot);
            $arr_edge = array_merge($arr_top, $arr_bot);
            $foo_arr_edge = foo($arr, $arr_edge);

            // append permutations of reduced array
            foreach($foo_arr_edge as $e_edge) {
                $perm_arr[] = $e_edge;
            }

            $arr_top[] = $arr;
        }
    }
    // case 2: inner array vs outer array
    // eg: array(1, 2, 3) vs array(array(10, 20, 30), array(100, 200, 300))
    // reduce the size of outer array until it reaches the base case
    else if(isset($arr1[0]) && (isset($arr2[0]) && is_array($arr2[0]))) {
        $foo_arr2 = array();

        $n_arr2 = count($arr2);
        // if the size of outer array is greater than 2 then reduce it until the size is 2
        if(2 < $n_arr2) {
            $arr_top = array();
            $arr_bot = $arr2;

            // get possible arrangements for further reduction
            // eg:
            // array(1, 2, 3) vs array(10, 20, 30),
            // array(1, 2, 3) vs array(100, 200, 300),
            // array(10, 20, 30) vs array(100, 200, 300),
            // ...
            while(0 < count($arr_bot)) {
                $arr = array_shift($arr_bot);
                $arr_edge = array_merge($arr_top, $arr_bot);
                $foo_arr_edge = foo($arr, $arr_edge);

                foreach($foo_arr_edge as $e_edge) {
                    $foo_arr2[] = $e_edge;
                }

                $arr_top[] = $arr;
            }
        }
        // if the size of outer array is 2 then get the permutations of its elements via the base case
        else if(2 == $n_arr2) {
            $foo_arr2 = foo($arr2[0], $arr2[1]);
        }

        // generate permutations from reduced array
        foreach($arr1 as $e1) {
            foreach($foo_arr2 as $e2) {
                $perm = $e1 .'-'. $e2;
                $perm_arr[] = $perm;
            }
        }
    }
    // base case: inner array vs inner array
    // eg: array(1, 2, 3) vs array(10, 20, 30)
    // generate permutations of two inner arrays
    else if(isset($arr1[0]) && (isset($arr2[0]) && !is_array($arr2[0]))) {
        foreach($arr1 as $e1) {
            foreach($arr2 as $e2) {
                $perm = $e1 .'-'. $e2;
                $perm_arr[] = $perm;
            }
        }
        foreach($arr2 as $e2) {
            foreach($arr1 as $e1) {
                $perm = $e2 .'-'. $e1;
                $perm_arr[] = $perm;
            }
        }
    }

    return $perm_arr;
}
?>

答案 2 :(得分:0)

我相信这是您正在寻找的答案:

<?php

$nL =   '
';
$arr = array(
        array(1, 2, 3),
        array(10, 20, 30),
        array(100, 200, 300),
    );

foreach ($arr[0] as $key => $val1) {
    foreach ($arr[1] as $val2) {
        foreach ($arr[2] as $val3) {
            echo $val1 . '-' . $val2 . '-' . $val3 . $nL;
        }
    }
}

foreach ($arr[0] as $key => $val1) {
    foreach ($arr[2] as $val2) {
        foreach ($arr[1] as $val3) {
            echo $val1 . '-' . $val2 . '-' . $val3 . $nL;
        }
    }
}

foreach ($arr[1] as $key => $val1) {
    foreach ($arr[0] as $val2) {
        foreach ($arr[2] as $val3) {
            echo $val1 . '-' . $val2 . '-' . $val3 . $nL;
        }
    }
}

foreach ($arr[1] as $key => $val1) {
    foreach ($arr[2] as $val2) {
        foreach ($arr[0] as $val3) {
            echo $val1 . '-' . $val2 . '-' . $val3 . $nL;
        }
    }
}

foreach ($arr[2] as $key => $val1) {
    foreach ($arr[0] as $val2) {
        foreach ($arr[1] as $val3) {
            echo $val1 . '-' . $val2 . '-' . $val3 . $nL;
        }
    }
}

foreach ($arr[2] as $key => $val1) {
    foreach ($arr[1] as $val2) {
        foreach ($arr[0] as $val3) {
            echo $val1 . '-' . $val2 . '-' . $val3 . $nL;
        }
    }
}

echo    'finished';
?>

享受。 =)