在 PHP 中生成数组的所有组合、配置和排列的最有效方法是什么?
问问题
10096 次
5 回答
7
这是获取所有排列的代码:
http://php.net/manual/en/function.shuffle.php#90615
用得到幂集的代码,排列是最大长度的排列,幂集应该是所有的组合。我不知道什么是性格,所以如果你能解释一下,那会有所帮助。
于 2009-11-05T10:56:31.560 回答
6
你可以使用这个类: http: //pear.php.net/package/Math_Combinatorics
并像这样使用它:
$combinatorics = new Math_Combinatorics;
$words_arr = array(
'one' => 'a',
'two' => 'b',
'three' => 'c',
'four' => 'd',
);
for ($i=count($words_arr)-1;$i>=1;$i--) {
echo '<br><br>' . $i . ':<br>';
$combinations_arr = $combinatorics->combinations($words_arr, $i);
foreach ($combinations_arr as $combinations_arr_item) {
echo implode(', ', $combinations_arr_item) . '<br>';
}
}
于 2012-05-05T23:15:39.083 回答
2
我想建议我的CombinationsGenerator解决方案,它生成数组项的组合。
它仅限于所有组合都是完整的长度,并且不重复任何项目。但我相信实施不会太难。
class CombinationsGenerator
{
public function generate(array $list): \Generator
{
if (count($list) > 2) {
for ($i = 0; $i < count($list); $i++) {
$listCopy = $list;
$entry = array_splice($listCopy, $i, 1);
foreach ($this->generate($listCopy) as $combination) {
yield array_merge($entry, $combination);
}
}
} elseif (count($list) > 0) {
yield $list;
if (count($list) > 1) {
yield array_reverse($list);
}
}
}
}
$generator = new \CombinationsGenerator();
foreach ($generator->generate(['A', 'B', 'C', 'D']) as $combination) {
var_dump($combination);
}
它是 PHP7 风格的,它使用了一个\Generator
“因为我相信这样做有充分的理由”。
于 2016-09-12T09:36:02.157 回答
1
/* Combinations */
function nCr($n, $r)
{
if ($r > $n)
{
return NaN;
}
if (($n - $r) < $r)
{
return nCr($n, ($n - $r));
}
$return = 1;
for ($i = 0; $i < $r; $i++)
{
$return *= ($n - $i) / ($i +1);
}
return $return;
}
/* Permutations */
function nPr($n, $r)
{
if ($r > $n)
{
return NaN;
}
if ($r)
{
return $n * (nPr($n -1, $r -1));
}
else
{
return 1;
}
}
于 2013-04-02T15:37:44.937 回答
0
我不得不修改@hejdav 的答案,使其包含部分组合,以便它完全提供所有结果。
我在互联网上搜索了这个解决方案,截至 2019 年 6 月,我相信这是唯一一个真正列出所有可能的、非重复的可能性的可公开访问的答案(任何地方)。
class CombinationsGenerator
{
/**
* Taken from https://stackoverflow.com/a/39447347/430062.
*
* @param array $list
* @return \Generator
*/
public function generate(array $list): \Generator
{
// Generate even partial combinations.
$list = array_values($list);
$listCount = count($list);
for ($a = 0; $a < $listCount; ++$a) {
yield [$list[$a]];
}
if ($listCount > 2) {
for ($i = 0; $i < count($list); $i++) {
$listCopy = $list;
$entry = array_splice($listCopy, $i, 1);
foreach ($this->generate($listCopy) as $combination) {
yield array_merge($entry, $combination);
}
}
} elseif (count($list) > 0) {
yield $list;
if (count($list) > 1) {
yield array_reverse($list);
}
}
}
}
于 2019-06-14T13:06:41.530 回答