我到处寻找这个,但无法完全找到它。 (我的PHP和数学技能让我失望了...) 我有一个包含例如三个字符串的数组(也可能更多!)(例如:“a”,“b”,“c”)。现在我想创建一个返回所有可能性的函数。我到处寻找并找到了一些很好的函数,他们以一切可能的方式移动了数组,但是他们并没有逐个删除一个值。所以他们有:
abc acb bac bca cab cba
哪个好,但是我需要一个将它提升到一个新水平的功能:
abc acb bac bca cab cba ac ca ab ba bc ba a b c
并且这无论多少值(让我们说最多10)。 整个晚上我一直在努力解决这个问题,有人能让我摆脱困境并为我解决这个谜题吗?或者给出一些建议。 感谢
答案 0 :(得分:1)
看起来你要求的是“电源组”。功率集包括空集,我不包括。
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
我认为从技术上讲,这不是一个权力集,因为我在比较集合时假设订单很重要。反正...
答案 1 :(得分:1)
与往常一样,以自己的方式解决问题会更有趣。您可以更轻松地修改代码以满足您的特殊需求,因为您知道自己在做什么:) 请参阅下面的测试脚本:
<?
$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";
?>
我只是回应了预期的输出,你可以添加一个结果数组,但那是你的一部分:)
输出:
[] //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
答案 2 :(得分:0)
在O'Reilly的PHP Cookbook, section 4.26上有一个排列的示例函数。它只创建固定大小的排列,但可以在循环中使用来处理任何大小,就像你需要它一样。
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