 ###### duandushang5148
2017-06-12 08:42 阅读 31

# 在PHP中生成独特的组合

I have a requirement to generate unique combinations from the given data set (n numbers) with each combination contains r values.

Basically looking to implement `C(n,r)=n!(r!(n−r)!)` formula in PHP.

Input data set {A,B,C,D} and need an unique combination of 3 values like below:

``````C(n,r)=C(4,3) = 4!/(3!(4−3)!)
= 4
``````

ABC ACD BCD BDA

(CDA,CAB,BCA etc are duplicates and should be truncated from output).

But my code below

``````<?php
function sampling(\$chars, \$size, \$combinations = array()) {

# if it's the first iteration, the first set
# of combinations is the same as the set of characters
if (empty(\$combinations)) {
\$combinations = \$chars;
}

# we're done if we're at size 1
if (\$size == 1) {
return \$combinations;
}

# initialise array to put new values in
\$new_combinations = array();

# loop through existing combinations and character set to create strings
foreach (\$combinations as \$combination) {
foreach (\$chars as \$char) {
if(\$combination != \$char)
\$new_combinations[] = \$combination . \$char;
}
}

# call same function again for the next iteration
return sampling(\$chars, \$size - 1, \$new_combinations);

}
?>
``````

returns below 64 arrays with duplicates

{ => string(3) "aaa" => string(3) "aab" => string(3) "aac" => string(3) "aad" => string(3) "aba" => string(3) "abb" => string(3) "abc" => string(3) "abd" => string(3) "aca" => string(3) "acb" => string(3) "acc" => string(3) "acd" => string(3) "ada" => string(3) "adb" => string(3) "adc" => string(3) "add" => string(3) "baa" => string(3) "bab" => string(3) "bac" => string(3) "bad" => string(3) "bba" => string(3) "bbb" => string(3) "bbc" => string(3) "bbd" => string(3) "bca" => string(3) "bcb" => string(3) "bcc" => string(3) "bcd" => string(3) "bda" => string(3) "bdb" => string(3) "bdc" => string(3) "bdd" => string(3) "caa" => string(3) "cab" => string(3) "cac" => string(3) "cad" => string(3) "cba" => string(3) "cbb" => string(3) "cbc" => string(3) "cbd" => string(3) "cca" => string(3) "ccb" => string(3) "ccc" => string(3) "ccd" => string(3) "cda" => string(3) "cdb" => string(3) "cdc" => string(3) "cdd" => string(3) "daa" => string(3) "dab" => string(3) "dac" => string(3) "dad" => string(3) "dba" => string(3) "dbb" => string(3) "dbc" => string(3) "dbd" => string(3) "dca" => string(3) "dcb" => string(3) "dcc" => string(3) "dcd" => string(3) "dda" => string(3) "ddb" => string(3) "ddc" => string(3) "ddd" }

Thanks in advance !!!

• 点赞
• 写回答
• 关注问题
• 收藏
• 复制链接分享

#### 1条回答默认 最新

• 已采纳

Say you have a set of 4 items and you want a random subset of 3 of them. You can do the following:

``````\$myset = [ "A","B","C", "D" ];

function randomSubset(\$set, \$size) {
\$array = array_pad(array_pad([],\$size,1),count(\$set),0); //Get an array like [ 1,1,1,0 ];
shuffle(\$array);
return array_intersect_key(\$set, array_filter(\$array));
}

print_r(randomSubset(\$myset,3));
``````

Now if you need all subsets of size N you can do some recursive magic:

``````function allSubsets(\$set, \$size) {
\$subsets = [];
if (\$size == 1) {
return array_map(function (\$v) { return [\$v]; },\$set);
}
foreach (allSubsets(\$set,\$size-1) as \$subset) {
foreach (\$set as \$element) {
if (!in_array(\$element,\$subset)) {
\$newSet = array_merge(\$subset,[\$element]);
sort(\$newSet);
if (!in_array(\$newSet,\$subsets)) {
\$subsets[] = array_merge(\$subset,[\$element]);
}
}
}
}
return \$subsets;

}

\$myset = [ "A","B","C", "D", "E" ];
print_r(allSubsets(\$myset,3));
``````
点赞 评论 复制链接分享