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

时间:2015-04-13 08:29:52

标签: php arrays character sequence

我试图用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";,它会对大写范围进行替换。

这很好,但我想包括大写范围,所以......有没有办法实现这个目标?

1 个答案:

答案 0 :(得分:0)

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

$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;
}