我想做一个函数,它能够使用a-z,0-9生成字母和可选数字的列表。
$output = array();
foreach(range('a','z') as $i) {
foreach(range('a','z') as $j) {
foreach(range('a','z') as $k) {
$output[] =$i.$j.$k;
}
}
}谢谢
示例:
myfunction($include, $length)用法类似于:
myfunction('a..z,0..9', 3);输出:
000
001
...
aaa
aab
...
zzz输出将包含字母和数字的所有可能组合。
发布于 2013-06-11 18:12:04
设置舞台
首先,使用range将诸如"0..9"之类的字符串扩展为"0123456789"
function expand_pattern($pattern) {
$bias = 0;
$flags = PREG_SET_ORDER | PREG_OFFSET_CAPTURE;
preg_match_all('/(.)\.\.(.)/', $pattern, $matches, $flags);
foreach ($matches as $match) {
$range = implode('', range($match[1][0], $match[2][0]));
$pattern = substr_replace(
$pattern,
$range,
$bias + $match[1][1],
$match[2][1] - $match[1][1] + 1);
$bias += strlen($range) - 4; // 4 == length of "X..Y"
}
return $pattern;
}它可以处理任意数量的可扩展模式,并注意保持它们在源字符串中的位置,例如
expand_pattern('abc0..4def5..9')将返回"abc01234def56789"。
一次计算所有结果
现在我们可以轻松地进行扩展了,下面是一个函数,它计算给定一个允许字符串和一个长度的笛卡尔乘积:
function cartesian($pattern, $length) {
$choices = strlen($pattern);
$indexes = array_fill(0, $length, 0);
$results = array();
$resets = 0;
while ($resets != $length) {
$result = '';
for ($i = 0; $i < $length; ++$i) {
$result .= $pattern[$indexes[$i]];
}
$results[] = $result;
$resets = 0;
for ($i = $length - 1; $i >= 0 && ++$indexes[$i] == $choices; --$i) {
$indexes[$i] = 0;
++$resets;
}
}
return $results;
}例如,要获得问题中描述的输出,您可以这样做
$options = cartesian(expand_pattern('a..z0..9'), 3);(我将扩展长度限制为2,这样输出就不会爆炸)。
动态生成结果
由于结果集可能非常大(随着$length呈指数级增长),一次生成结果集可能被证明是令人望而却步的。在这种情况下,可以重写代码,使其依次返回每个值(迭代器样式),这在PHP5.5中由于generators而变得非常简单
function cartesian($pattern, $length) {
$choices = strlen($pattern);
$indexes = array_fill(0, $length, 0);
$resets = 0;
while ($resets != $length) {
$result = '';
for ($i = 0; $i < $length; ++$i) {
$result .= $pattern[$indexes[$i]];
}
yield $result;
$resets = 0;
for ($i = $length - 1; $i >= 0 && ++$indexes[$i] == $choices; --$i) {
$indexes[$i] = 0;
++$resets;
}
}
}。
发布于 2013-06-11 17:48:51
有关生成所有可能组合的代码,请参阅以下答案:https://stackoverflow.com/a/8567199/1800369
您只需要添加$length参数来限制组合的大小。
发布于 2013-06-11 18:22:28
您可以使用递归函数
假设你的意思是它可以是任意数量的层数,你可以使用一个递归函数来生成一个排列数组,例如:
/**
* take the range of characters, and generate an array of all permutations
*
* @param array $range range of characters to itterate over
* @param array $array input array - operated on by reference
* @param int $depth how many chars to put in the resultant array should be
* @param int $currentDepth internal variable to track how nested the current call is
* @param string $prefix internal variable to know what to prefix the current string with
* @return array permutations
*/
function foo($range, &$array, $depth = 1, $currentDepth = 0, $prefix = "") {
$start = !$currentDepth;
$currentDepth++;
if ($currentDepth > $depth) {
return;
}
foreach($range as $char) {
if ($currentDepth === $depth) {
$array[] = $prefix . $char;
continue;
}
foo($range, $array, $depth, $currentDepth, $prefix . $char);
}
if ($start) {
return $array;
}使用上面的函数,初始化返回变量并调用它:
$return = array();
echo implode(foo(range('a', 'z'), $return, 3), "\n");您的输出将是从aaa到zzz的所有三个字符组合:
aaa
aab
...
zzy
zzz数值参数决定了函数的递归程度:
$return = array();
echo implode(foo(range('a', 'z'), $return, 1), "\n");
a
b
c
...Here's a live example。
https://stackoverflow.com/questions/17040134
复制相似问题