简体   繁体   中英

PHP - All permutations in a 2D array - Unique and ordered values

I have a 2d array. Assuming each position i have a number os candidates to fill it.

Ex:

Position 0 -> Candidates: 1,2,3
Position 1 -> Candidates: 3,4,5
Position 2 -> Candidates: 4,5

Translating:

Array_Position(
  array('1', '2', '3'),
  array('3', '4','5'),
  array('4', '5')   
);

I want all the combinations, with 2 restrictions:

  1. No repetitions (if a candidate is already in one position, it can´t appear again in another position).
    This can´t happen:
    1-4-4
    3-3-4

  2. A candidate can´t be "smaller" than his previous.
    This can´t happen:
    1-5-4
    3-5-4

In this particular case, the all possible combinations would be:
1-3-4
1-3-5
1-4-5
2-3-4
2-3-5
2-4-5
3-4-5

I saw some answers like this:

<?php       
    function array_cartesian() {
        $_ = func_get_args();
        if(count($_) == 0)
            return array(array());
        $a = array_shift($_);
        $c = call_user_func_array(__FUNCTION__, $_);
        $r = array();
        foreach($a as $v)
            foreach($c as $p)
                $r[] = array_merge(array($v), $p);
        return $r;
    }

    $cross = array_cartesian(
        array('1', '2', '3'),
        array('3', '4','5'),
        array('4', '5') 
    );

    print_r($cross);

?>

but none of them resolve the 2 restrictions.

Any help?

Tks!

Since any candidate can't be smaller than his previous, then any position can't be repeated in the chain. The following code does the trick, check if it works for you.

<?php

function permute()
{
    $result = array();

    if (func_num_args() == 0)
        return $result; // empty array

    foreach (func_get_arg(0) as $value)
        nextPermute($result, $value, $value, 1, func_get_args());

    return $result;
}

function nextPermute(&$result_array, $permute_value,
                    $last_value, $next_arg, $all_args)
{
    if ($next_arg < count($all_args))
    {
        foreach ($all_args[$next_arg] as $value)
            if ($value > $last_value)
                nextPermute($result_array, $permute_value . '-' . $value, $value, $next_arg + 1, $all_args);
    }
    else
        array_push($result_array, $permute_value);
}

$cross = permute(
    array('1', '2', '3'),
    array('3', '4', '5'),
    array('4', '5')
);

print_r($cross);

?>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM