我有一个任务让我有点疯狂,有一节是关于单词排列的,在我浏览互联网后,我发现了一个做排列的功能,如下所示:
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个或更多字符的排列吗?
长度为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
如果这些都不能回答您的问题,请澄清;)