Permutation and Combination in PhP

家住魔仙堡 提交于 2021-01-29 09:32:08

问题


I I want to compute the permutations 5p2, 5p3, 5p4 and 5p5 from the array [1,2,3,4,5] The function below only runs 5p5. To run 5p2, 5p3, 5p4 I will have to manually iterate through the array using a for...loop. Please help me.

//function to return permutations 5p5 array
        function combinationArray($myarr) {
            $results = [];
            $current = [];
            $next = function($myarr) use(&$next,&$results,&$current) {
                $l = count($myarr);
                if($l === 1) {
                    $current []= $myarr[0];
                    $results []= intval(implode($current)); //use this for array containing numbers only
                    //$results []= implode($current); //use this for array containing alphabets
                    array_pop($current);
                    return;
                }
                for($i=0; $i<$l; $i++) {
                    $tmpArr = $myarr;
                    $current []= array_splice($tmpArr,$i,1)[0];
                    $next($tmpArr);
                    array_pop($current);
                }
            };
            $next($myarr);
            return $results;
        }

//Manual iteration of 5c2 will be like this....about 120 different modules.....

$wordArray = str_split($sWord, 1);
$newArray1 = $wordArray[0]; $newArray2 = $wordArray[1];$newArray3 = $wordArray[2]; $newArray4 = $wordArray[3]; $newArray5 = $wordArray[4]; 
    //12
for($a = 0; $a < count($newArray1); $a++){
    for($b = 0; $b < count($newArray2); $b++){
        $aux = $newArray1[$a].$newArray2[$b]; array_push($result52, $aux);                              
    }
}
//13
for($a = 0; $a < count($newArray1); $a++){
    for($c = 0; $c < count($newArray3); $c++){
        $aux = $newArray1[$a].$newArray3[$c]; array_push($result52, $aux);                              
    }
}
//14
for($a = 0; $a < count($newArray1); $a++){
    for($d = 0; $d < count($newArray4); $d++){
        $aux = $newArray1[$a].$newArray4[$d]; array_push($result52, $aux);                              
    }
}
//15
for($a = 0; $a < count($newArray1); $a++){
    for($e = 0; $e < count($newArray5); $e++){
        $aux = $newArray1[$a].$newArray5[$e]; array_push($result52, $aux);                              
    }
}
//21
for($b = 0; $b < count($newArray2); $b++){
    for($a = 0; $a < count($newArray1); $a++){      
        $aux = $newArray2[$b].$newArray1[$a]; array_push($result52, $aux);                              
    }
}
//23
for($b = 0; $b < count($newArray2); $b++){
    for($c = 0; $c < count($newArray3); $c++){      
        $aux = $newArray2[$b].$newArray3[$c]; array_push($result52, $aux);                              
    }
}
//24
for($b = 0; $b < count($newArray2); $b++){
    for($d = 0; $d < count($newArray4); $d++){      
        $aux = $newArray2[$b].$newArray4[$d]; array_push($result52, $aux);                              
    }
}
//25
for($b = 0; $b < count($newArray2); $b++){
    for($e = 0; $e < count($newArray5); $e++){  
        $aux = $newArray2[$b].$newArray5[$e]; array_push($result52, $aux);                              
    }
}
//31
for($c = 0; $c < count($newArray3); $c++){
    for($a = 0; $a < count($newArray1); $a++){
        $aux = $newArray3[$c].$newArray1[$a]; array_push($result52, $aux);                              
    }
}
//32
for($c = 0; $c < count($newArray3); $c++){
    for($b = 0; $b < count($newArray2); $b++){
        $aux = $newArray3[$c].$newArray2[$b]; array_push($result52, $aux);                              
    }
}
//34
for($c = 0; $c < count($newArray3); $c++){
    for($d = 0; $d < count($newArray4); $d++){
        $aux = $newArray3[$c].$newArray4[$d]; array_push($result52, $aux);                              
    }
}
//35
for($c = 0; $c < count($newArray3); $c++){
    for($e = 0; $e < count($newArray5); $e++){
        $aux = $newArray3[$c].$newArray5[$e]; array_push($result52, $aux);                              
    }
}
//41
for($d = 0; $d < count($newArray4); $d++){
    for($a = 0; $a < count($newArray1); $a++){
        $aux = $newArray4[$d].$newArray1[$a]; array_push($result52, $aux);                              
    }
}
//42
for($d = 0; $d < count($newArray4); $d++){
    for($b = 0; $b < count($newArray2); $b++){
        $aux = $newArray4[$d].$newArray2[$b]; array_push($result52, $aux);                              
    }
}
//43
for($d = 0; $d < count($newArray4); $d++){
    for($c = 0; $c < count($newArray3); $c++){
        $aux = $newArray4[$d].$newArray3[$c]; array_push($result52, $aux);                              
    }
}
//45
for($d = 0; $d < count($newArray4); $d++){
    for($e = 0; $e < count($newArray5); $e++){
        $aux = $newArray4[$d].$newArray5[$e]; array_push($result52, $aux);                              
    }
}
//51
for($e = 0; $e < count($newArray5); $e++){
    for($a = 0; $a < count($newArray1); $a++){
        $aux = $newArray5[$e].$newArray1[$a]; array_push($result52, $aux);                              
    }
}
//52
for($e = 0; $e < count($newArray5); $e++){
    for($b = 0; $b < count($newArray2); $b++){
        $aux = $newArray5[$e].$newArray2[$b]; array_push($result52, $aux);                              
    }
}
//53
for($e = 0; $e < count($newArray5); $e++){
    for($c = 0; $c < count($newArray3); $c++){
        $aux = $newArray5[$e].$newArray3[$c]; array_push($result52, $aux);                              
    }
}
//54
for($e = 0; $e < count($newArray5); $e++){
    for($d = 0; $d < count($newArray4); $d++){
        $aux = $newArray5[$e].$newArray4[$d]; array_push($result52, $aux);                              
    }
}

$result52 = array_unique($result52); //remove duplicates... but the indexes dont align.
$result52 = array_reduce($result52,"myfunction");//convert the array into a string bcos of the indexes              
$result52 = str_split($result52, 2); //split the new string in twos into an array to get correct indexes
print_r($result52);

Thank you all.


回答1:


I fished some things in the internet. I hope this suits your needs.

I don't take any credit for this. It's a combination of these two solutions: Generating a Power Set and Implementing Heap's Algorithm

<?php

$arr1 = [1,2,3];

/**
 * Permutation.
 */
class Permutation
{
    /**
     * @var array
     */
    protected $items;

    /**
     * @var array
     */
    protected $result = [];

    /**
     * @param array $array
     * @param int   $permutation
     */
    public function __construct($array, $permutation)
    {
        if (count($array) < $permutation) {
            throw new Exception("That's impossible for me :/");
        }

        // first get all the unique subsets with the permutation's length
        $subsets = $this->getPowerSet($array, $permutation);

        // genereate the permutation for each subset
        foreach ($subsets as $subset) {
            $this->setItems($subset)->heaps($this->n, $this->items);
        }

        sort($this->result);
    }

    /**
     * Get result.
     *
     * @return array
     */
    public function getResult()
    {
        return $this->result;
    }

    /**
     * Set items.
     *
     * @param array $items
     */
    public function setItems($items)
    {
        $this->items = $items;
        $this->n = count($items);
        return $this;
    }

    private function swap(&$items, $i, $j)
    {
        $temp = $items[$i];
        $items[$i] = $items[$j];
        $items[$j] = $temp;
    }

    /**
     * This is Heap's algorithm, generates all possible permutations of n items.
     *
     * @link https://en.wikipedia.org/wiki/Heap%27s_algorithm
     *
     * @param int   $n
     * @param array $items
     */
    private function heaps($n, &$items)
    {
        if ($n == 1) {
            $this->result[] = implode('', $items);
        } else {
            for ($i = 0; $i < $n; ++$i) {
                $this->heaps($n - 1, $items);
                if ($n % 2 == 0) {
                    $this->swap($items, 0, $n - 1);
                } else {
                    $this->swap($items, $i, $n - 1);
                }
            }
        }
    }

    /**
     * Way to get the Power Set (set of all unique subsets)
     * 
     * @link https://www.php.net/manual/en/function.shuffle.php#88408
     * 
     * @param array $in
     * @param int   $length
     */
    private function getPowerSet($in, $length) {
        $count = count($in);
        $members = pow(2,$count);
        $return = array();
        for ($i = 0; $i < $members; $i++) {
            $b = sprintf("%0".$count."b",$i);
            $out = array();
            for ($j = 0; $j < $count; $j++) {
                if ($b{$j} == '1') $out[] = $in[$j];
            }
            if (count($out) === $length) {
                $return[] = $out;
            }
        }
        return $return;
    }
}

$permutation = new Permutation($arr1, 2);

echo "<pre>";
print_r($permutation->getResult());
echo "</pre>";


来源:https://stackoverflow.com/questions/61481619/permutation-and-combination-in-php

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!