排除字符串的某些排列

时间:2015-01-06 22:35:05

标签: php algorithm permutation

代码最初来自this thread

如何排除某些排列?例如,如果我将$ str设置为“heyy”并希望它排除其中包含“yy”(两个y在一起)的所有排列,我该怎么做?

所以它会打印例如“hyey”,但不是“hyye”。

mb_internal_encoding('UTF-8');

// function to generate and print all N! permutations of $str. (N = strlen($str)).
function permute($str,$i,$n)
{
    if ($i == $n)
    {
        print "$str\n";
    }
    else
    {
        for ($j = $i; $j < $n; $j++)
        {
            swap($str,$i,$j);
            permute($str, $i+1, $n);
            swap($str,$i,$j); // backtrack.
        }
    }
}

function swap(&$str,$i,$j) {
    $chars = array();
    for ($p = 0; $p < mb_strlen($str); $p++) {
        $chars[] = mb_substr($str, $p, 1);
    }
    $temp = $chars[$i];
    $chars[$i] = $chars[$j];
    $chars[$j] = $temp;
    $str = implode($chars);
}

$str = "heyy";

permute($str, 0, mb_strlen($str)); // call the function.

提前致谢!

1 个答案:

答案 0 :(得分:1)

这是你正在寻找的吗?

function permute($str,$i,$n)
{
    if ($i == $n && strpos($str, 'yy') === false)    // note the extra condition
    {
        print "$str\n";
    }
    else
    {
        for ($j = $i; $j < $n; $j++)
        {
            swap($str,$i,$j);
            permute($str, $i+1, $n);
            swap($str,$i,$j); // backtrack.
        }
    }
}

如果这变得更复杂,你也可以为它编写一个单独的函数(这个例子是遍历一个禁止的子串列表):

$skip = array('yy', 'xx');

function valid_permutation($str)
{
    global $skip;
    // check all forbidden substrings
    foreach ($skip as $substring)
        if (strpos($str, $substring) !== false)
            return false;
    // no substring matches
    return true;
}

function permute($str,$i,$n)
{
    if ($i == $n && valid_permutation($str))
    {
        print "$str\n";
    }
    else
    {
        for ($j = $i; $j < $n; $j++)
        {
            swap($str,$i,$j);
            permute($str, $i+1, $n);
            swap($str,$i,$j); // backtrack.
        }
    }
}