排除字符串的某些排列


Exclude certain permutations of a string

代码最初来自这个线程。

如何排除某些排列?例如,如果我$str设置为"hey"并希望它排除所有包含"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.

提前感谢!

这是你要找的吗?

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.
        }
    }
}