php – 如何生成受限制的变换的排列?

最好用一个例子来解释.

假设您有一个替换列表,将使用PHP,因为这是我的目标:

$s = array(
    'p' => array('b', 'f', 'v'),
    'a' => array('e'),
    't' => array('d', '')
);

上述意味着’p’可以用’b’,’f’或’v’代替; ‘e’;’a’;并且’不’或’不’.每次只允许对每个列表进行一次替换.

所以产生’pa’的所有替换将给出:’ba’,’fa’,’va’,’pe’,’be’,’fe’,’ve’

并产生’papa’的所有替换:’baba’,’fafa’,’vava’,’pepe”bebe’,’fefe’,’veve’

我可以很容易地通过上层元素进行置换:

// 2 ^ count($s) permutations, assuming count($s) < 31
$k = 1 << count($s);
for ($l = 0; $l < $k; $l++)
{
    $x = $input;
    for ($m = $l, reset($s); $m; $m >>= 1, next($s))
        if ($m & 1)
            // Will fail here, maybe this should be an outer loop but how?
            // For now, just replacing with the first element
            $x = str_replace(key($s), current($s)[0], $x);
    print $x."\n";
}

只是不能正确地围绕如何做正确的内部替换.

我考虑过将$s转换为一系列简单的替换:

$t = array(
    array('p' => 'b'),
    array('a' => 'e'),
    array('p' => 'b', 'a' => 'e'),
    array('p' => 'f'),
    ...

但这仍然让我回到了同样的问题.

任何意见,将不胜感激.

最佳答案 你对for循环的管理与数组指针的结合过于复杂.

以下是一种非常天真的方法,可以通过采用其他策略(如递归)来简化.

function generate_permutations($subtitutions, $subject) {
    $permutations = array($subject);

    foreach ($subtitutions as $search => $replacements) {
        $new_permutations = array();

        foreach ($replacements as $replacement) {
            foreach ($permutations as $permutation) {
                if (strpos($permutation, $search) === false) {
                    continue;
                }

                $new_permutations[] = str_replace($search, $replacement, $permutation);
            }
        }

        $permutations = array_merge($permutations, $new_permutations);
    }

    return $permutations;
}

注意:我只测试了您的示例.

点赞