给定一个如下的数组
$array = ('1', '2', '3', '4', '5', '6', '7');
我正在寻找一种方法来生成所有可能的组合,每个组合r需要最少数量的元素。 (例如,如果r = 5,那么它将返回包含至少5个元素的所有可能组合)
答案 0 :(得分:2)
组合可以表示为
n C r = n! /(r! - (n - r)!)
首先,我们将$n
确定为数组中元素的数量。 $r
是每个组合中元素的最小数量。
$a = ['1', '2', '3', '4', '5', '6', '7']; // the array of elements we are interested in
// Determine the `n` and `r` in nCr = n! / (r! * (n-r)!)
$r = 5;
$n = count($a);
接下来,我们将$max
确定为可由$n
二进制数字表示的最大数字。也就是说,如果$n = 3
,则$max = (111)
2 = 7
。为此,我们首先创建一个空字符串$maxBinary
并向其添加$n
个1
个。然后我们将其转换为十进制,并将其存储在$max
。
$maxBinary = "";
for ($i = 0; $i < $n; $i++)
{
$maxBinary .= "1";
}
$max = bindec($maxBinary); // convert it into a decimal value, so that we can use it in the following for loop
然后,我们会列出从0
到$max
的每个二进制数字,并存储$r
个1
个数量超过$allBinary = array(); // the array of binary numbers
for ($i = 0; $i <= $max; $i++)
{
if (substr_count(decbin($i), "1") >= $r) // we count the number of ones to determine if they are >= $r
{
// we make the length of the binary numbers equal to the number of elements in the array,
// so that it is easy to select elements from the array, based on which of the digits are 1.
// we do this by padding zeros to the left.
$temp = str_pad(decbin($i), $n, "0", STR_PAD_LEFT);
$allBinary[] = $temp;
}
}
的数字。
$combs = array(); // the array for all the combinations.
$row = array(); // the array of binary digits in one element of the $allBinary array.
foreach ($allBinary as $key => $one)
{
$combs[$key] = "";
$row = str_split($one); // we store the digits of the binary number individually
foreach ($row as $indx => $digit)
{
if ($digit == '1') // if the digit is 1, then the corresponding element in the array is part of this combination.
{
$combs[$key] .= $a[$indx]; // add the array element at the corresponding index to the combination
}
}
}
然后,我们使用与上面相同的技巧为我们的组合选择元素。我相信这些评论足够解释。
echo count($combs);
就是这样。你完成了!
现在,如果您有类似
的内容29
然后它会给你{{1}}。
我只是在看到你的问题后才读到这个问题,作为一个新手,我发现这些有用:
此外,这里有一些文档的快速链接,可以帮助将来看到这个的人:
答案 1 :(得分:2)
k
个n
个项目的组合可以使用以下函数递归定义:
function combinationsOf($k, $xs){
if ($k === 0)
return array(array());
if (count($xs) === 0)
return array();
$x = $xs[0];
$xs1 = array_slice($xs,1,count($xs)-1);
$res1 = combinationsOf($k-1,$xs1);
for ($i = 0; $i < count($res1); $i++) {
array_splice($res1[$i], 0, 0, $x);
}
$res2 = combinationsOf($k,$xs1);
return array_merge($res1, $res2);
}
以上内容基于递归定义,选择k
n
个x
元素,可以在列表中修复元素C(k-1, xs\{x})
,并且有x
个组合其中包含res1
(即C(k,xs\{xs})
)和x
组合,但不包含res2
(即代码中的$array = array('1', '2', '3', '4', '5', '6', '7');
function combinationsOf($k, $xs){
if ($k === 0)
return array(array());
if (count($xs) === 0)
return array();
$x = $xs[0];
$xs1 = array_slice($xs,1,count($xs)-1);
$res1 = combinationsOf($k-1,$xs1);
for ($i = 0; $i < count($res1); $i++) {
array_splice($res1[$i], 0, 0, $x);
}
$res2 = combinationsOf($k,$xs1);
return array_merge($res1, $res2);
}
print_r ($array);
print_r(combinationsOf(5,$array));
//print_r(combinationsOf(5,$array)+combinationsOf(6,$array)+combinationsOf(7,$array));
)。
完整示例:
{{1}}
答案 2 :(得分:0)
function arrToBit(Array $element) {
$bit = '';
foreach ($element as $e) {
$bit .= '1';
}
$length = count($element);
$num = bindec($bit);
$back = [];
while ($num) {
$back[] = str_pad(decbin($num), $length, '0', STR_PAD_LEFT);
$num--;
}
//$back[] = str_pad(decbin(0), $length, '0', STR_PAD_LEFT);
return $back;
}
function bitToArr(Array $element, $bit) {
$num = count($element);
$back = [];
for ($i = 0; $i < $num; $i++) {
if (substr($bit, $i, 1) == '1') {
$back[] = $element[$i];
}
}
return $back;
}
$tags = ['a', 'b', 'c'];
$bits = arrToBit($tags);
$combination = [];
foreach ($bits as $b) {
$combination[] = bitToArr($tags, $b);
}
var_dump($combination);