数组中的所有可能组合 - 递归?

3

我有一个让我困惑的问题,希望有人能帮忙解答。我认为这个问题可能需要使用递归和/或排列组合来解决,但我不是一个足够优秀的(PHP)程序员。

$map[] = array("0", "1", "2", "3");
$map[] = array("4", "5", "6", "7");
$map[] = array("8", "9", "10", "11");
$map[] = array("12", "13", "14", "15");
$map[] = array("16", "17", "18", "19");
$map[] = array("20", "21", "22", "23");

$map数组的最大长度仅限于"6"。

我正在寻找一种方法来生成所有可能的组合。以下是一些有效的组合:

示例1:

$map[] = array("0", "1", "2", "3", "4", "5", "6", "7");
$map[] = array("8", "9", "10", "11");
$map[] = array("12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", );
$map[] = array("23");

示例2:

$map[] = array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23");

示例3:

$map[] = array("0", "1");
$map[] = array("2", "3", "4", "5", "6", "7", "8");
$map[] = array("9", "10", "11");
$map[] = array("12");
$map[] = array("13", "14", "15", "16", "17", "18", "19", "20");
$map[] = array("21", "22", "23");

每个地图数组中的值必须按升序排列,例如,此示例为无效:
$map[] = array("0", "1", "4");
$map[] = array("3", "5");
etc...

Hope this can be done.


当你说地图数组限制为六时,那么你所有的有效示例都超过了六... - omar-ali
@omar-ali 示例是$map的第二维。 - Teaqu
@omar-ali 的意思是 $map 中只有 6 个索引(注意 $map 是一个数组)。 - naththedeveloper
你能说一下你的最终目标是什么吗?也许你的方法不太对,你实际上想做什么? - naththedeveloper
我正在努力寻找最佳的分组。数值(0、1、2、3等)指的是某个时间段的“得分”(0 = 00:00-01:00,1 = 01:00-02:00等)。我只能将这些得分分组并“汇总”到6个时间“块”中。我正在尝试找到哪些分组或“块”可以产生最好的总和。 - Tjeerd Kramer
请参考这篇帖子 - LF00
2个回答

0
一个递归解决方案。
<?php
function combination($remaining, $current, $combinations) {
    $e = array_shift($remaining);
    $combinations[$current][] = $e;

    if(empty($remaining)) {
        print_r($combinations);
        return;
    }

    combination($remaining, $current, $combinations);
    // 6 Limit remove for all solutions
    if ($current < 6) {
        combination($remaining, $current + 1, $combinations);
    }
}


$remaining = range(0, 23);

combination($remaining, 0, array());

如果你想要存储[0,23]的所有解决方案,那么你会遇到麻烦。

0

由于您需要数字的范围,我将问题简化为排列组合问题。

以下是一个shell脚本(作为node.js脚本从终端执行),用于计算您需要的范围:

#!/usr/bin/env nodejs

// Config
var blocksTotal     = 3;    // 6
var numbersTotal    = 6;    // 24
var perms           = [];   // Permutations

// Start the loop
(function divideHours(numbersToGo, blocksToGo, arr) {

    // What block is this? [1 .. 3]
    var block = blocksTotal - --blocksToGo;

    // Divide numbers
    if (block < blocksTotal)
        for (var hour = 0; hour <= numbersToGo; hour++) {
            if (block == 1) var arr = [];
            arr[block-1] = hour;
            divideHours(numbersToGo-hour, blocksToGo, arr);
        }
    // Last block? Assign rest of numbers
    else {
        perms.push(arr.concat([numbersToGo]));
        console.log(arr.concat([numbersToGo]).toString());
    }
})(numbersTotal, blocksTotal);

测试较小的范围和数字,您将获得以下排列组合:

0,0,6
0,1,5
0,2,4
0,3,3
0,4,2
0,5,1
0,6,0
1,0,5
1,1,4
1,2,3
1,3,2
1,4,1
1,5,0
2,0,4
2,1,3
2,2,2
2,3,1
2,4,0
3,0,3
3,1,2
3,2,1
3,3,0
4,0,2
4,1,1
4,2,0
5,0,1
5,1,0
6,0,0

看起来没问题吧? 现在试试更大的数字,结果数组存储在perms中。

如果你明确想要数组中提到的每个数字,你可以使用一些计数器和数学方法来获得这种类型的数组。例如:
3,1,2 -> [1,2,3],[4],[5,6]
2,0,4 -> [1,2],[],[3,4,5,6]

这里是一个使用6个块和24个数字的片段:

``` ... 7,2,2,10,0,3 7,2,2,10,1,2 7,2,2,10,2,1 7,2,2,10,3,0 7,2,2,11,0,2 7,2,2,11,1,1 7,2,2,11,2,0 7,2,2,12,0,1 7,2,2,12,1,0 7,2,2,13,0,0 7,2,3,0,0,12 7,2,3,0,1,11 7,2,3,0,2,10 ... 但是这个列表是无穷无尽的。 ```

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接