排列算法

时间:2017-03-12 15:22:48

标签: php

我正在寻找一个考虑到数组顺序的高效组合函数。例如,我想生成" hello world"的所有组合。但我不想让任何一个逆转,#34;世界你好"。我目前有一个组合功能,但它太多了。

简单示例:

$text = "Hello World"
$arr = explode(" ",$text); // string to array

并给出:

$result = combo_function($arr);
var_dump($result);

"Hello World"
"Hello" 
"World"

我不想反向:

"World Hello"
  • 关键是我希望它比组合更快。

目前我正在使用它:

 // careful, this is very labor intensive ( O(n^k) )

public function buildSearchCombinations(&$set, &$results)
{
    for ($i = 0; $i < count($set); $i++) {

        $results[] = (string) $set[$i];
        $tempset = $set;
        array_splice($tempset, $i, 1);
        $tempresults = array();
        $this->buildSearchCombinations($tempset, $tempresults);

        foreach ($tempresults as $res) {
            $results[] = trim((string) $set[$i]) . " " . (string) trim($res);
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我有一个相当奇怪的解决方案:

<?php

function supersetmember($set, $index) {
    $keys = array_reverse(str_split(decbin($index)));
    $member = [];
    foreach ($keys as $k => $v) {
        if ($v == 1) { 
            $member[] = $set[$k];
        }

    }
    return $member;
}


$text = "Hello World";
$arr = explode(" ",$text);
$total = pow(2,count($arr)); //Total permutations on size of set n is 2^n 
$superset = [];
for ($i = 0;$i < $total;$i++) {
    $superset[] = supersetmember($arr,$i);
}
print_r($superset);

说明:

有2 ^ n组构成一组大小为n(包括空集)。 您可以将每个集合映射为从0到(n-1)的自然数。 如果将该数字转换为二进制,则数字为1将指示您的子集将包含的原始集合的哪些成员。例如:

设置=(A,B);

超级成员2(十进制)= 10(二进制),这意味着子集将包含 第二个但不是第一个成员(我们从右到左读取数字,从最低有效数字到最高有效数字)。

这样做的好处是你有一种“fausset”算法(函数超集),你给它一个集合和你想要的子集,你得到那个子集。

在当前版本中获取单个子集的复杂性为O(n),但如果您使用位移实现它,则可以将其缩减为O(log n)总计算法将为O(2^n)是不可避免的,因为要生成O(2^n)个子集。