Я пытаюсь создать последовательный массив символов из n элементов с помощью PHP. Что я хочу сделать, так это если я скажу функции генерировать первые, скажем, 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;
}
Других решений пока нет …