Algorithm to get all possible string combinations from array up to certain length

后端 未结 12 960
攒了一身酷
攒了一身酷 2020-12-01 02:22

What is the best algorithm to get all possible string combinations from a given array with a minimum & maximum length value.

Note: This adds complexity since the

12条回答
  •  被撕碎了的回忆
    2020-12-01 03:03

    Solution

    function combinationsByLenth($arr, $len) {
        $combinations = [];
        $select = array_fill(0, $len, 0);
        $selectCount = count($select);
        $arrCount = count($arr);
        $possibleCombinations = pow($arrCount, $selectCount);
    
        while ($possibleCombinations-- > 0) {
            $combination = '';
    
            foreach ($select as $index) {
                $combination .= $arr[$index];
            }
    
            $combinations[] = $combination;
    
            for ($i = $selectCount - 1; $i >= 0; $i--) {
                if ($select[$i] !== ($arrCount - 1)) {
                    $select[$i]++;
                    break;
                } else {
                    $select[$i] = 0;
                }
            }
        }
    
        return $combinations;
    }
    
    function combinationsByMinMax($arr, $min, $max) {
        $combinations = [];
    
        for ($i = $min; $i <= $max; $i++) {
            $combinations = array_merge($combinations, combinationsByLenth($arr, $i));
        }
    
        return $combinations;
    }
    
    print_r(combinationsByMinMax($arr, 1, 5));
    

    Output

    Array
    (
        [0] => a
        [1] => b
        [2] => c
        [3] => 1
        [4] => 2
        [5] => 3
        [6] => aa
        [7] => ab
        [8] => ac
        [9] => a1
        ...
        [9320] => 3332c
        [9321] => 33321
        [9322] => 33322
        [9323] => 33323
        [9324] => 3333a
        [9325] => 3333b
        [9326] => 3333c
        [9327] => 33331
        [9328] => 33332
        [9329] => 33333
    )
    

    Rationale

    • Avoid recursive solutions for this type of problem in PHP (note, I like recursion in languages optimized to handle it better) to avoid stack issues as the length grows.
    • Break the function up into two separate functions, one that implements min and max length, and one that gets the possible combinations for a specific length to promote reuse and clarity.
    • Limit function calls within the 2 functions as much as possible to enhance performance (this algorithm gets heavy fast!)

    How I Developed This Solution

    I started out with a function that handled the specific case of combinations of length 5, refactored to generalize the algorithm, refactored to generalize the algorithm, etc. I've put up a quick gist so you can see the iterations to get to this working version as a case study of how to approach building this type of algorithm:

    https://gist.github.com/AdamJonR/5278480

提交回复
热议问题