我有这个数组:
$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));