简体   繁体   English

置换算法

[英]Algorithm for permutations

I am looking for an efficient combinations function that would take into account the order of the array. 我正在寻找一种有效的组合函数,该函数应考虑数组的顺序。 For example I want to generate all of the combinations of "hello world" but I don't want any of it reversed "world hello". 例如,我想生成“ hello world”的所有组合,但我不希望其中任何一个都反转为“ world hello”。 I currently have a combinations function but it's too much. 我目前有一个组合功能,但是太多了。

Simple example : 简单的例子:

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

And gives: 并给出:

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

"Hello World"
"Hello" 
"World"

I do NOT want the inverse: 我不希望相反:

"World Hello"
  • the key is that I want it to be faster than combinations if possible. 关键是如果可能的话,我希望它比组合更快。

Currently I am using this: 目前,我正在使用此:

 // 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);
        }
    }
}

I have a rather odd solution to this: 我对此有一个相当奇怪的解决方案:

<?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);

Explanation: 说明:

There's 2^n sets that constitute a set of size n (including the empty set). 有2 ^ n个集合构成大小为n的集合(包括空集合)。 You can map each of those sets as a natural number from 0 to (n-1). 您可以将每个集合映射为0到(n-1)之间的自然数。 If you convert that number to binary then the digits that are 1 will indicate which members of the original set your subset will contain. 如果将该数字转换为二进制,则数字1将指示您的子集将包含原始集合的哪些成员。 Example: 例:

Set = (A,B); 设置=(A,B);

Superset member 2(decimal) = 10 (binary) which means the subset will include the second but not first member (we read the number from right to left as in from least significant to most significant digit). 超集成员2(十进制)= 10(二进制),这意味着该子集将包括第二个成员但不包括第一个成员(我们从右到左读取数字,从最低有效位到最高有效位)。

The advantage of doing this is that you have a sort of a "fausset" algorithm (function supersetmember) which you give it a set and the subset you want and you get that subset. 这样做的好处是,您有一种“模糊集合”算法(函数超集成员),可以为其提供一个集合和所需的子集,然后获得该子集。

The complexity of getting a single subset in the current version is O(n) but if you implement it with bit shifting you can reduce it to O(log n) In total the algorithm will be O(2^n) which is unavoidable because there are O(2^n) subsets to be generated. 在当前版本中获取单个子集的复杂度为O(n)但如果通过位移实现它,则可以将其降低为O(log n)总的来说,算法将为O(2^n) ,这是不可避免的,因为有O(2^n)个子集要生成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM