如何获取包括空白的所有独特组合(无关的项目顺序)



我有这个数组:

$array = array( 57, 53, 52 );

我想获得这些数字的所有唯一组合(项目的顺序无关(。

我想要以下线的结果:

// 57
// 57, 53
// 57, 53, 52
// 53
// 52
// 52, 57

我正在使用此功能,但是这返回了值的每个组合,并且由于我不在乎它们的顺序,它们都是相同的结果:

function my_function( $array ) {
    $combinations = array();
    $words = sizeof( $array );
    $combos = 1;
    for( $i = $words; $i > 0; $i-- ) {
        $combos *= $i;
    }
    while( sizeof( $combinations ) < $combos ) {
        shuffle($array);
        $combo = implode( " ", $array );
        if( !in_array( $combo, $combinations ) ) {
            $combinations[] = $combo;
        }
    }
    return $combinations;
}
print_r( my_function( $array ) );

我该如何实现?

<?php
function my_function($array){
    $combs = [[]]; // adding empty set for better code clarity
    sort($array); // sort the array to avoid verbose code to handle duplicate combinations
    $set = [];
    foreach($array as $index => $element){
        $temp = [];
        foreach($combs as $curr_comb){
            $new_comb = $curr_comb;
            $new_comb[] = $element;
            $hashed_comb = implode(",",$new_comb);
            if(!isset($set[$hashed_comb])){
                $temp[] = $new_comb;
                $set[$hashed_comb] = true;
            }
        }
        $combs = array_merge($combs,$temp);
    }
    return array_slice($combs,1); // removing the empty set initially added
}
print_r(my_function([57,53,52]));
print_r(my_function([3,3,3]));

演示: https://3v4l.org/f3ihs

  • 我们在使代码看起来很简单之前添加了一个空的组合[]
  • 我们通过将当前元素添加到先前生成的组合集中来生成组合。就像,首先是 [],后来变成 [],[57],后来又(在第一个foreach循环的下一个迭代中(变为 [],[57],[53],[57,53]等。
  • 我们进行implode()并插入set以记住组合以避免重复。

由于顺序无关紧要,似乎我们可以按顺序努力。从第一个数字开始,然后查找所有组合,然后作为我们的首发数字移至第二个组合,依此类推。而且由于我喜欢递归功能(功能递归是其自身的回报(,所以这就是我的方式:

function unique_combinations( $array, $prefix = '' ) {
    $combinations = array();
    $count = count($array);
    // I use a for loop just to count the number of times to run. Since I'm using array_shift, the array will keep getting smaller
    for( $i = 0; $i < $count; $i++ ) {
        $number = array_shift($array);
        // Grab our current result (this number and any prefixes
        $this_result = trim( "$prefix $number" );
        $combinations[] = $this_result;
        // Now, if the array still has numbers in it, run the function on those numbers and combine results
        if ( count($array) > 0 ) {
            $combinations = array_merge($combinations, unique_combinations( $array, $this_result ) );
        }
    }
    return $combinations;
}
print_r( unique_combinations( [57,58,59] ) );

具有单个匿名函数sort和早期array_unique的类似且相似的简短递归方法。应该给您想要的东西,为简单起见,值按升序排序:

// all the logic
$getAllCombinations = function($array) {
    $result = [];
    sort($array);
    $getOrderedCombinations = function ($combination_base, &$result) use (&$getOrderedCombinations) {
        array_push($result,$combination_base);
        if(count($combination_base) > 1) {
            foreach($combination_base as $key => $val) {
                $newcombo = $combination_base;
                unset($newcombo[$key]);
                $getOrderedCombinations($newcombo,$result);
            }
        }
    };
    $getOrderedCombinations($array,$result);
    return array_unique($result,SORT_REGULAR);
};

// execution
$array = array( 57, 53, 52  );
var_dump($getAllCombinations($array));

最新更新