我面临一个大问题。我需要生成精确的7个数字组合,并且我使用7个forloops编写了一个代码,并且它的工作正常,数量非常少。请检查附件,这样你就会非常清楚我需要什么。 请提供PHP结果。
<?php
// I need the combinations for this commented numbers
// 1, 7, 13, 19, 25, 31, 2, 8, 14, 20, 26, 32, 3, 9, 15,
// 21, 27, 33, 4, 10, 16, 22, 28, 34, 5, 11, 17, 23, 29,
// 35, 6, 12, 18, 24, 30, 36
$string=array(1,7,13,19,25,31,2,8,14,20,26,32,3,9,15,21,27,33,4,10,16,22,28,34);
$len=count($string);
$c=0;
ob_start();
for ($e = 0; $e < $len - 6; $e++)
{
for ($f = $e+1; $f < $len - 5; $f++)
{
for ($g = $f+1; $g < $len - 4; $g++)
{
for ($h = $g+1; $h < $len - 3; $h++)
{
for ($i = $h+1; $i < $len - 2; $i++)
{
for ($j = $i + 1; $j < $len - 1; $j++)
{
for ($k = $j + 1; $k < $len; $k++)
{
$c++;
$output[] = $string[$e] . "," .
$string[$f] . "," .
$string[$g] . "," .
$string[$h] . "," .
$string[$i] . "," .
$string[$j] . "," .
$string[$k];
ob_flush();
}
ob_flush();
}
ob_flush();
}
ob_flush();
}
ob_flush();
}
ob_flush();
}
ob_flush();
}
echo count($output);
?>
我需要输出相同,如下所述。 输出:
passed numbers $string=array(1, 7, 13, 19, 25, 31, 2, 8, 14) and the out put is below
count of combinations = 36
Array
(
[0] => 1,7,13,19,25,31,2
[1] => 1,7,13,19,25,31,8
[2] => 1,7,13,19,25,31,14
[3] => 1,7,13,19,25,2,8
[4] => 1,7,13,19,25,2,14
[5] => 1,7,13,19,25,8,14
[6] => 1,7,13,19,31,2,8
[7] => 1,7,13,19,31,2,14
[8] => 1,7,13,19,31,8,14
[9] => 1,7,13,19,2,8,14
[10] => 1,7,13,25,31,2,8
[11] => 1,7,13,25,31,2,14
[12] => 1,7,13,25,31,8,14
[13] => 1,7,13,25,2,8,14
[14] => 1,7,13,31,2,8,14
[15] => 1,7,19,25,31,2,8
[16] => 1,7,19,25,31,2,14
[17] => 1,7,19,25,31,8,14
[18] => 1,7,19,25,2,8,14
[19] => 1,7,19,31,2,8,14
[20] => 1,7,25,31,2,8,14
[21] => 1,13,19,25,31,2,8
[22] => 1,13,19,25,31,2,14
[23] => 1,13,19,25,31,8,14
[24] => 1,13,19,25,2,8,14
[25] => 1,13,19,31,2,8,14
[26] => 1,13,25,31,2,8,14
[27] => 1,19,25,31,2,8,14
[28] => 7,13,19,25,31,2,8
[29] => 7,13,19,25,31,2,14
[30] => 7,13,19,25,31,8,14
[31] => 7,13,19,25,2,8,14
[32] => 7,13,19,31,2,8,14
[33] => 7,13,25,31,2,8,14
[34] => 7,19,25,31,2,8,14
[35] => 13,19,25,31,2,8,14
)
答案 0 :(得分:8)
function factorial($factVal) {
$factorial = 1;
while ($factVal > 1) {
$factorial *= $factVal--;
}
return $factorial ;
}
function permutations($numObjs,$numInSet) {
return round(factorial($numObjs) / factorial($numObjs - $numInSet));
}
function combinations($numObjs,$numInSet) {
return round(factorial($numObjs) / factorial($numObjs - $numInSet)) / factorial($numInSet);
}
$string=array(1,7,13,19,25,31,2,8,14,20,26,32,3,9,15,21,27,33,4,10,16,22,28,34);
echo 'Number of Combinations = '.combinations(count($string),7).'<br />';
echo 'Number of Permutations = '.permutations(count($string),7).'<br />';
答案 1 :(得分:0)
尽管我无法向您提供完整的代码,但我可以告诉您,即使是更高的组合,我也已经完成了此操作,您需要使用 RECURSIVE FUNCTIONS 而不是使用嵌套循环。< / p>
递归函数使您可以灵活地超越7。
NLV
答案 2 :(得分:0)
如果你真的想要这些组合,你可以做这样的事情......
这里是:
function combinations($set,$length) {
$combinations = array();
for($i = 0, $n = count($set); $i <= ($n - $length); $i++) {
$combination = array();
$combination[] = $set[$i];
if($length > 1) {
$combination = array_merge(
$combination,
combinations(array_slice($set,1+$i), $length-1)
);
}
$combinations[] = $combination;
}
return $combinations;
}
$allCombinations = combinations($allYourNumbers, 7);
编辑将参数的顺序更改为array_slice
答案 3 :(得分:0)
我不确定我是否理解你的问题,但我认为你想要在数组中生成所有可以从“从左到右”获得的数字组合,即如果我们采用排序的数组(让我们说从1到50)并且第一个数字已经是4,那么所有后面的数字应该大于4,如果第二个数字是12,所有后面的数字应该大于12,依此类推。
所以事实是这样的数字组合的数量是如此之大,无论你使用什么算法 - 在某个数组大小,它都是不易处理的,即真正生成所有数字需要太长时间,因为它们太多了。
如果您从m
个号码中取出n
个号码,则binomial(n,m)
有多种可能性(binomial(n,m)
是二项式系数n
和m
)。
因此,特别是对于您的情况binomial(n,7)
很有意思。然而,二项式系数是一个非常快速增长的函数。即如果你把参数放大一点,结果会大得多。
binomial(9,7) = 36
binomial(10,7) = 120
binomial(11,7) = 330
binomial(12,7) = 792
...
binomial(15,7) = 6435
binomial(20,7) = 77520
binomial(30,7) = 2035800
你看,对于30个数字,已经存在很多可能性,并且需要时间来枚举所有这些可能性。所以,你的算法可能有多聪明,在数组大小的某个点上它只能因为大量的可能性而放弃。
我在C中写了一个小程序:
#define PRINTITEMS 0
#include <stdio.h>
#include <stdlib.h>
typedef struct _comb{
int x1;
int x2;
int x3;
int x4;
int x5;
int x6;
int x7;
} comb;
void generateAll7Possibilities(int* a,int n, comb* target){
int i1, i2, i3, i4, i5, i6, i7;
int c = 0;
for (i1=0; i1<n-6; i1++){
for (i2=i1+1; i2<n-5; i2++){
for (i3=i2+1; i3<n-4; i3++){
for (i4=i3+1; i4<n-3; i4++){
for (i5=i4+1; i5<n-2; i5++){
for (i6=i5+1; i6<n-1; i6++){
for (i7=i6+1; i7<n; i7++){
target[c].x1=a[i1];
target[c].x2=a[i2];
target[c].x3=a[i3];
target[c].x4=a[i4];
target[c].x5=a[i5];
target[c].x6=a[i6];
target[c].x7=a[i7];
if (PRINTITEMS){
printf("%d %d %d %d %d %d %d\n", target[c].x1, target[c].x2, target[c].x3, target[c].x4, target[c].x5, target[c].x6, target[c].x7);
}
}
}
}
}
}
}
}
}
int main(){
printf("This is enumerator\n");
int array[36];
int i;
for (i=0; i<36; ++i){
array[i]=i;
printf("%d\n",array[i]);
}
printf("Starting generation");
comb* target= malloc(sizeof(comb)*8347680);
generateAll7Possibilities(array,36,target);
printf("Generation finished");
}
如果不打印值,上述程序运行正常。但是,一旦开始打印值,就没有机会完成。
所以我建议你尝试删除输出并生成所有可能的组合。
答案 4 :(得分:0)
这是一种替代方法(不是在PHP中),它允许确定组合集中任意组合的组合。
在组合集中,存在有限数量的不同组合。这意味着可以为每个组合分配序列号,并且可以将序列号转换为组合集。关键部分是以下例程.... get_array_offset()。
int get_array_offset (x, y) {
int offset = 0;
while (1) {
choices = choose (x, y); // x choose y
if (sequence <= choices)
break;
sequence -= choices;
x--;
offset++;
}
return offset;
}
让我们假设我们正在处理一个24选择7组合,并且我们所有的值都存储在数组中
valueArray[24] = { ....};
对于给定的序列号,要找到组合中的第一项是......
sequence = ...; // sequence number in combination set
index = 0;
offset = get_array_offset (24 - 1 - index, 7 - 1);
index += offset;
/* valueArray[index] <--- first item in the combination */
offset = get_array_offset (24 - 2 - index, 7 - 2);
index += offset;
/* valueArray[index] <--- second item in the combination */
offset = get_array_offset (24 - 3 - index, 7 - 3);
index += offset;
/* valueArray[index] <--- third item in the combination */
... And so forth (fits nicely into a loop) ...
我已经实施了这样的算法已经有一段时间了。要点就在那里,但我可能会有一个错误的错误。类似的逻辑可以适用于排列问题。
希望这有帮助。