I\'ve looked everywhere for this online, but couldn\'t completely find it. (my PHP and math skills are letting my down for this one...) I have an array containing for exampl
It looks like you're asking for the "power set". the power set includes the empty set, which i wont include.
require_once 'Math/Combinatorics.php';
$set = range('a', 'c');
$permutationSizes = range(1, count($set));
$combinatorics = new Math_Combinatorics;
$result = array();
foreach ($permutationSizes as $permutationSize) {
$result = array_merge($result, $combinatorics->permutations($set, $permutationSize));
}
print_r($result);
http://pear.php.net/package/Math_Combinatorics
I guess technically this isnt a power set because i'm assuming order matters when comparing sets. anyway...
As always, it's much more fun to solve the problem your own way. You can modify your code to fit your special needs much easier then, because you know what you are doing :) See my test script below:
<?
$a = array("a", "b", "c");
function getAll($prefix, $remaining)
{
echo $prefix."\n";
if (count($remaining) == 0) return;
if (count($remaining) == 1)
{
echo $prefix.$remaining[0]."\n";
return;
}
for ($i = 0; $i < count($remaining); $i++)
{
$t = $remaining;
unset($t[$i]);
$t = array_values($t);
getAll($prefix.$remaining[$i], $t);
}
}
echo "<pre>\n";
getAll('', $a);
echo "</pre>\n";
?>
I just echo'd the intended output, you could add up a result array instead, but that's your part :)
Output:
[] //empty value is included, but blank lines won't show up here, so I wrote []
a
ab
abc
ac
acb
b
ba
bac
bc
bca
c
ca
cab
cb
cba
There's an example function for permutations on O'Reilly's PHP Cookbook, section 4.26. It only creates permutations of a fixed size, but can be used in a loop to deal with any size like you need it.
function pc_next_permutation($p, $size) {
// slide down the array looking for where we're smaller than the next guy
for ($i = $size - 1; $p[$i] >= $p[$i+1]; --$i) { }
// if this doesn't occur, we've finished our permutations
// the array is reversed: (1, 2, 3, 4) => (4, 3, 2, 1)
if ($i == -1) { return false; }
// slide down the array looking for a bigger number than what we found before
for ($j = $size; $p[$j] <= $p[$i]; --$j) { }
// swap them
$tmp = $p[$i]; $p[$i] = $p[$j]; $p[$j] = $tmp;
// now reverse the elements in between by swapping the ends
for (++$i, $j = $size; $i < $j; ++$i, --$j) {
$tmp = $p[$i]; $p[$i] = $p[$j]; $p[$j] = $tmp;
}
return $p;
}
$set = explode(' ', 'a b c');
// $all will contain the final output
$all = $set;
while(count($set) > 1) {
$perms = array();
$size = count($set) - 1;
$perm = range(0, $size);
$j = 0;
do {
foreach ($perm as $i) { $perms[$j][] = $set[$i]; }
} while ($perm = pc_next_permutation($perm, $size) and ++$j);
foreach ($perms as $p) {
$all[] = implode(' ', $p);
}
array_pop($set);
}
// display results
foreach($all as $each) {
echo $each . "\n";
}
a
b
c
a b c
a c b
b a c
b c a
c a b
c b a
a b
b a
Live example