PHP - 生成由 a-z 和 A-Z 组成的 n 个项目的顺序字符数组



我正在尝试使用 PHP 生成一个包含 n 个项目的顺序字符数组。我想做的是,如果我告诉函数生成第一个,比如说,6000 个项目,得到类似的东西:

Array (
    [0] => a
    [1] => b
    [2] => c
    ...
    [26] => A
    [27] => B
    [28] => C
    ...
    [5178] => BaF
)

我已经有了该功能的一些起始部分。我可以有这个字符范围:

array_merge(range("a", "z"), range("A", "Z"))

我可以像这样生成字符序列:

if (!empty($count)) {
    if (is_numeric($count)) {
        if ($count > 0) {
            $t = $output[] = "a";
            for ($i = 0; $i < $count; $i++) {
                $output[] = ++$t;
            }
        }
    }
}

这实际上会给我一个从 a 到 z 的字符序列,当它达到字符限制时,它会像 aa、ab、ac 等一样,直到它再次达到限制,然后它会像 aaa、aab、aac 等等,依此类推......

如果我用$t = $output[] = "A";替换$t = $output[] = "a";,它会做同样的事情,但对于大写范围。

这很好,但我也想包括大写范围,所以......有没有办法做到这一点?

我已经编写了自己的算法来实现您想要的。这很复杂,但我已尽力在评论中解释它。

$chars = array_merge(range("a", "z"), range("A", "Z"));
/*
 * You can comfortably change the value of numChars
 * to your liking and the code will generate appropriate
 * sequence. For example, if you hardcode the value of $numChars
 * to 3 then you will get a sequence like so:
 * a, b, c, aa, ab, ac, ba, bb, bc, ca, cb, cc, aaa, aab...
 */
$numChars = count($chars);
$output = array();
$count = 6000;
if (!empty($count)) {
    if (is_numeric($count)) {
        if ($count > 0) {
            for ($i = 0; $i < $count; $i++) {
                $charPositions = getCharPositions($i, $numChars);
                $str = "";
                foreach ($charPositions as $pos) {
                    $str .= $chars[$pos];
                }
                $output[] = $str;
            }
        }
    }
}
echo "<pre>";
print_r($output);
echo "</pre>";
function getCharPositions($num, $base)
{
    /*
     * First we find which section the number belongs to
     * and we find how many positions it has moved forward in that section
     * For example, if you want to loop from a to e then the base will be 5
     * if $num is 27 the result is 'ec'
     * Since, it has 2 characters it's in the second section
     * What it means is that it went from first to last for the first position,
     * ie, a to e, and for the second position it moved 22 steps ahead,
     * which is basically (27 - (5^1))
     */
    $section = 1;
    $limit = $base;
    while (true) {
        $temp = $num - $limit;
        if ($temp < 0) {
            break;
        }
        $num = $temp;
        $limit *= $base;
        $section++;
    }
    /*
     * Once we find out how many steps ahead it has moved in the last section,
     * we just need to convert it into a number with the specified base,
     * the code below is basically something like converting a decimal number to
     * a hexadecimal number, However, each digit of the resultant number is stored
     * separately in an array because each of this digit will actually be used as
     * position to get the character from the characters array
     */
    $positionsFilled = 0;
    $result = array();
    while ($num > 0) {
        $remainder = $num % $base;
        $num = (int)($num / $base);
        array_unshift($result, $remainder);
        $positionsFilled++;
    }
    /*
     * Here we prepend zeros for remaining positions
     * because the length of the string should be the
     * same as the section it belongs to
     */
    while ($positionsFilled < $section) {
        array_unshift($result, 0);
        $positionsFilled++;
    }
    return $result;
}

最新更新