1

I have a function that take a one dimensional array and returns all the possible permutations of the elements within the array;

function array_2D_permute($items, $perms = array()) {
static $permuted_array = array();
    if (empty($items)) {
        $permuted_array[]=$perms;
        #print_r($new);
        #print join(' ', $perms) . "\n";
    }  else {
        for ($i = count($items) - 1; $i >= 0; --$i) {
             $newitems = $items;
             $newperms = $perms;
             list($foo) = array_splice($newitems, $i, 1);
             array_unshift($newperms, $foo);
             array_2D_permute($newitems, $newperms);
         }
         return $permuted_array;
    }
}

$arr1=array("Architecture","Mexico","Periodicals");
$result1=array_2D_permute($arr1);
print_r($result1);

$arr2=array("Apple","Boat","Cat");
$result2=array_2D_permute($arr2);
print_r($result2);

The first time the function is called, it works as expected, however the second time it is called, it also includes elements from the first array. I can't figure out why this is.

Appreciate the help.

Mr B
  • 3,553
  • 5
  • 41
  • 63
  • I amended the code so that the static $permuted_array; line now reads static $permuted_array = array(); but its still returning elements from the first element in the second array. – Mr B Mar 02 '11 at 14:09

3 Answers3

2

I know this question is old, but here's an alternative solution passing the return array by reference:

function pc_permute($items, $perms = array( ), &$return = array()) {
    if (empty($items)) {
        $return[] = $perms;
    }  else {
        for ($i = count($items) - 1; $i >= 0; --$i) {
             $newitems = $items;
             $newperms = $perms;
             list($foo) = array_splice($newitems, $i, 1);
             array_unshift($newperms, $foo);
             pc_permute($newitems, $newperms,$return);
         }
        return $return;
    }
}
Julien Bourdon
  • 1,605
  • 17
  • 28
2

Because you are using static $permuted_array;

you must use

static $permuted_array;      // declare static var, if you don't want to use static property of variable, then why are you using this
$permuted_array = array();   // set its value to array()

using static $permuted_array = array(); will not set its value to array() after first iteration

function array_2D_permute($items, $perms = array(), $isNew = false) {
static $permuted_array = array();

if($isNew) 
   $permuted_array = array();


    if (empty($items)) {
        $permuted_array[]=$perms;
        #print_r($new);
        #print join(' ', $perms) . "\n";
    }  else {
        for ($i = count($items) - 1; $i >= 0; --$i) {
             $newitems = $items;
             $newperms = $perms;
             list($foo) = array_splice($newitems, $i, 1);
             array_unshift($newperms, $foo);
             array_2D_permute($newitems, $newperms);
         }
         return $permuted_array;
    }
}

$arr1=array("Architecture","Mexico","Periodicals");
$result1=array_2D_permute($arr1, array(), true);      //
print_r($result1);

$arr2=array("Apple","Boat","Cat");
$result2=array_2D_permute($arr2, array(), true);     ///
print_r($result2);

one more parameter is added $isNew. Send true if you want to get result for new array.

Gaurav
  • 26,880
  • 8
  • 47
  • 76
  • I amended the code so that the static $permuted_array; line now reads static $permuted_array = array(); but its still returning elements from the first element in the second array. – Mr B Mar 02 '11 at 14:32
  • use $permuted_array = array(); after static $permuted_array; – Gaurav Mar 02 '11 at 16:58
  • This returns only one permutation of each array. – Mr B Mar 02 '11 at 17:15
  • Thanks for your help Gaurav, I made the changed you outlined to my code. Each array is meant hold all the possible permutations of the array elements, instead this is what I'm getting; `Array ( [0] => Array ( [0] => Periodicals [1] => Mexico [2] => Architecture ) ) Array ( [0] => Array ( [0] => Cat [1] => Boat [2] => Apple ) )` – Mr B Mar 02 '11 at 17:20
  • Thanks for all your help Guarav, appreciate it. I've tried to set the $isNew to true in various places in the code but it still doesn't work as expected. – Mr B Mar 02 '11 at 17:39
  • code i have written is working as expected. Please check if you have missed something. – Gaurav Mar 02 '11 at 17:42
  • Sincere apologies, Guarav, you're right. Code works now as expected. Many thanks. – Mr B Mar 02 '11 at 17:46
0

fixed version

protected function array_2D_permute($items, $perms = array(), $reset = true) {
        static $permuted_array;
        if ($reset) {
            $permuted_array = array();
        }
        if (empty($items)) {
            $permuted_array[] = $perms;
        } else {
            for ($i = count($items) - 1; $i >= 0; --$i) {
                $newitems = $items;
                $newperms = $perms;
                list($foo) = array_splice($newitems, $i, 1);
                array_unshift($newperms, $foo);
                $this->array_2D_permute($newitems, $newperms, false);
            }
            return $permuted_array;
        }
    }

you can use it as $perms = array_2D_permute($arr);

Qcho
  • 1