如何创建字符串的排列(长度为10个字符或更长)?

时间:2012-02-11 05:12:52

标签: php algorithm anagram

我的任务让我有点疯狂,有一节处理单词排列,在浏览互联网后我发现了一个排列函数,如下图所示:

function permute($str) {
    if (strlen($str) < 2) {
        return array($str);
    }
    $permutations = array();
    $tail = substr($str, 1);
    foreach (permute($tail) as $permutation) {
        $length = strlen($permutation);
        for ($i = 0; $i <= $length; $i++) {
            $permutations[] = substr($permutation, 0, $i) . $str[0] . substr($permutation, $i);
        }
    }

    return $permutations;
}

这表示结果:

print_r(array_unique(permute("abcdefghi"))); // found 362880
print_r(array_unique(permute("abcdefghij"))); // error

问题是,此功能只能执行9个字符的所有排列(大约362880种组合,长时间使浏览器无法响应微小时间)。尝试执行最多10个字符的排列时,将显示错误消息:

致命错误:允许的内存大小耗尽134217728个字节(尝试分配35个字节)

您是否有解决方案或其他方式进行长度超过10个字符的排列?

1 个答案:

答案 0 :(得分:3)

长度为N的字符串的排列数为N!

因此,如果您只是在寻找排列数量,那么这样做:

function factorial($n) {
    if( $n == 0) return 1;
    if( $n < 3) return $n;
    return $n*factorial($n-1);
}
function permute($str) {
    return factorial(strlen($str));
}

但是,如果您尝试随机获得这些排列,请尝试以下方法:

function permute($str) {
    $l = strlen($str);
    $a = str_split($str);
    $ret = "";
    while($l > 0) {
        $i = rand(0,$l-1);
        $ret .= $a[$i];
        array_splice($a,$i,1);
        $l--;
    }
    return $ret;
}

如果您尝试强制所有N!排列,请尝试:

ini_set("memory_limit",-1);
set_time_limit(0);
// your brute-force code here

如果这些都没有回答你的问题,请澄清;)