查找具有限制的所有可能的字符串组合

时间:2018-05-25 00:31:27

标签: php arrays algorithm combinations

我需要帮助在PHP中创建一个算法,给定一个字母数组(表示为字符串)和这些字母表的分组数组(也是一个字符串数组),返回一个包含所有可能组合的数组的数组基于这些分组的字符串。以下示例将明确说明 -

如果输入数组为['A', 'B', 'C']且分组为['AB', 'BC'],则返回输出:

  1. 没有任何限制 [['A','B','C'], ['AB,'C'], ['A','BC'], ['AC','B'], ['ABC']]
  2. 分组的限制应为[['A','B','C'], ['AB,'C'], ['A','BC']]
  3. 之所以这样,是因为'ABC'和'AC'都不允许分组,并且想法是分组只有在属于指定数组时才存在。在这种情况下,由于'AB'和'BC'是唯一可能的分组,因此输出包含它们。第一个输出仅用于演示目的,但算法应生成第二个输出。唯一的另一个限制是单个组合中不能有重复的字母表。因此以下输出不正确:

    [['A','B','C'], ['AB,'C'], ['A','BC'], ['AB','BC'], ['AC','B'], ['ABC']]

    因为“B”在['AB','BC']

    中是重复的

    我发现的类似问题是here,但在此问题的“结果”中对哪些数字可以组合在一起没有限制。

    如果我觉得这听起来很混乱,我很抱歉,但如果您有任何问题,我一定会澄清。

2 个答案:

答案 0 :(得分:0)

生成此类分区的最简单方法是递归(我认为)。

首先,将限制表示为布尔(或0/1)2d矩阵。对于您的案例图,有连接(边)A-BB-C,邻接矩阵为[[0,1,0][1,0,1],[0,1,0]]

从空数组开始。在每个递归级别,将下一个元素(A,然后是B,然后是C)添加到所有可能的组中并添加到单独的组中。

(在C I等语言中,每个组使用位掩码,通过位或运算快速确定组是否允许添加当前元素)

  First level:   add A and get:   
              [[A]]
  Second level:  add B both in existing group and in separate one: 
              [[A, B]],                [[A],[B]]
  Third Level:  you add C only with:  
              [[A, B], C],       [[A],[B, C]], [[A],[B], [C]]

答案 1 :(得分:0)

您可以使用您关联的帖子中的答案。我为你改编了:

function generate_groups($collection) {
    if (count($collection) == 1) {
        yield [$collection];
        return;
    }
    $first = $collection[0];
    foreach (generate_groups(array_slice($collection, 1)) as $smaller) {
        foreach (array_values($smaller) as $n => $subset) {
            yield array_merge(
                array_slice($smaller, 0, $n),
                [array_merge([$first], $subset)],
                array_slice($smaller, $n+1)
            );
        }
        yield array_merge([[$first]], $smaller);
    }
}

$input = ['A', 'B', 'C'];
$groupings = ['AB', 'BC'];

foreach (generate_groups($input) as $groups) {
    $are_groups_ok = true;
    foreach ($groups as $group) {
        $compact = implode($group);
        if (strlen($compact) != 1 and !in_array($compact, $groupings)) {
            $are_groups_ok = false;
        }
    }
    if ($are_groups_ok) {
        echo "[" . implode("], [", array_map("implode", $groups)) . "]\n";
    }
}

打印:

[A], [BC]
[AB], [C]
[A], [B], [C]