我需要从给定的数据集(n个数字)生成唯一的组合,每个组合包含r值。
基本上希望在PHP中实现C(n,r)=n!(r!(n−r)!)
公式。
输入数据集{A,B,C,D},需要3个值的唯一组合,如下所示:
C(n,r)=C(4,3) = 4!/(3!(4−3)!)
= 4
ABC ACD BCD BDA
(CDA,CAB,BCA等是重复的,应该从输出中截断)。
但我的代码
<?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);
}
?>
返回64个带有重复项的数组
{[0] =&gt; string(3)&#34; aaa&#34; [1] =&GT; string(3)&#34; aab&#34; [2] =&GT;字符串(3)&#34; aac&#34; [3] =&GT; string(3)&#34; aad&#34; [4] =&GT; string(3)&#34; aba&#34; [5] =&GT; string(3)&#34; abb&#34; [6] =&GT; string(3)&#34; abc&#34; [7] =&GT; string(3)&#34; abd&#34; [8] =&GT; string(3)&#34; aca&#34; [9] =&GT; string(3)&#34; acb&#34; [10] =&GT; string(3)&#34; acc&#34; [11] =&GT; string(3)&#34; acd&#34; [12] =&GT; string(3)&#34; ada&#34; [13] =&GT; string(3)&#34; adb&#34; [14] =&GT; string(3)&#34; adc&#34; [15] =&GT; string(3)&#34; add&#34; [16] =&GT; string(3)&#34; baa&#34; [17] =&GT; string(3)&#34; bab&#34; [18] =&GT; string(3)&#34; bac&#34; [19] =&GT; string(3)&#34; bad&#34; [20] =&GT; string(3)&#34; bba&#34; [21] =&GT; string(3)&#34; bbb&#34; [22] =&GT; string(3)&#34; bbc&#34; [23] =&GT; string(3)&#34; bbd&#34; [24] =&GT; string(3)&#34; bca&#34; [25] =&GT; string(3)&#34; bcb&#34; [26] =&GT; string(3)&#34; bcc&#34; [27] =&GT; string(3)&#34; bcd&#34; [28] =&GT; string(3)&#34; bda&#34; [29] =&GT; string(3)&#34; bdb&#34; [30] =&GT; string(3)&#34; bdc&#34; [31] =&GT; string(3)&#34; bdd&#34; [32] =&GT; string(3)&#34; caa&#34; [33] =&GT; string(3)&#34; cab&#34; [34] =&GT; string(3)&#34; cac&#34; [35] =&GT; string(3)&#34; cad&#34; [36] =&GT; string(3)&#34; cba&#34; [37] =&GT; string(3)&#34; cbb&#34; [38] =&GT; string(3)&#34; cbc&#34; [39] =&GT; string(3)&#34; cbd&#34; [40] =&GT; string(3)&#34; cca&#34; [41] =&GT; string(3)&#34; ccb&#34; [42] =&GT; string(3)&#34; ccc&#34; [43] =&GT; string(3)&#34; ccd&#34; [44] =&GT; string(3)&#34; cda&#34; [45] =&GT; string(3)&#34; cdb&#34; [46] =&GT; string(3)&#34; cdc&#34; [47] =&GT; string(3)&#34; cdd&#34; [48] =&GT; string(3)&#34; daa&#34; [49] =&GT; string(3)&#34; dab&#34; [50] =&GT; string(3)&#34; dac&#34; [51] =&GT;字符串(3)&#34;爸爸&#34; [52] =&GT; string(3)&#34; dba&#34; [53] =&GT; string(3)&#34; dbb&#34; [54] =&GT; string(3)&#34; dbc&#34; [55] =&GT; string(3)&#34; dbd&#34; [56] =&GT; string(3)&#34; dca&#34; [57] =&GT; string(3)&#34; dcb&#34; [58] =&GT; string(3)&#34; dcc&#34; [59] =&GT; string(3)&#34; dcd&#34; [60] =&GT; string(3)&#34; dda&#34; [61] =&GT; string(3)&#34; ddb&#34; [62] =&GT; string(3)&#34; ddc&#34; [63] =&GT; string(3)&#34; ddd&#34; }
提前致谢!!!
答案 0 :(得分:1)
假设您有一组4个项目,并且您想要其中3个项目的随机子集。您可以执行以下操作:
$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));
在沙箱中查看:http://sandbox.onlinephpfunctions.com/code/a68f3b2f1abc285424ccadbaab8a12fc4928bb8d
现在,如果你需要大小为N的所有子集,你可以做一些递归魔术:
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));
沙盒:http://sandbox.onlinephpfunctions.com/code/01b55f0c1eb55ee82a67175d2551c164ffb2bf87
答案 1 :(得分:0)
这是一个从一组数字生成唯一组合的代码。
如果您有一组数字,例如1,3,4,7,12
,则可以生成X
个数字集,这些数字都是唯一的,没有重复。
第一个函数在PHP 7.4
或更高版本中起作用,第二个函数使用键存储值。两者都基于基准运行良好。
function get_combos74($map, $size, &$generated = [], $loop = 1, $i = 0, $prefix = [])
{
if ($loop == 1) {
sort($map);
}
for (; $i < count($map); $i++) {
if ($loop < $size) {
get_combos74($map, $size, $generated, $loop + 1, $i + 1, [...$prefix, $map[$i]]);
} else {
$generated[] = [...$prefix, $map[$i]];
}
}
return $generated;
}
function get_combosSTR($map, $size, &$generated = [], $loop = 1, $i = 0, $prefix = '')
{
if ($loop == 1) {
sort($map);
}
for (; $i < count($map); $i++) {
if ($loop < $size) {
get_combosSTR($map, $size, $generated, $loop + 1, $i + 1, "$prefix{$map[$i]}:");
} else {
$generated["$prefix{$map[$i]}"] = 0;
}
}
return $generated;
}