Как я могу сгенерировать последовательность чисел, как
1 2 4 8 11 12 14 18 …
(плюс 10 каждые 4 номера) со следующими дополнительными требованиями:
$input = 24;
1 2 4 8 11 12 14 18 21 22 24
$input = 20;
1 2 4 8 11 12 14 18
Вот что я попробовал до сих пор:
<?php
// sample user input
$input = 20;
$number = 1;
$counter = 0;
$array = array();
//conditions
while ($counter < 4) {
$counter++;
array_push($array, $number);
$number += $number;
}
//outputs
for ($x = 0; $x < count($array); $x++) {
echo $array[$x];
echo " ";
}
Код: (демонстрация)
function arrayBuilder($max,$num=1){
$array=[];
for($i=0; ($val=($num<<$i%4)+10*floor($i/4))<=$max; ++$i){
$array[]=$val;
}
return $array;
}
echo implode(',',arrayBuilder(28)),"\n"; // 1,2,4,8,11,12,14,18,21,22,24,28
echo implode(',',arrayBuilder(28,2)),"\n"; // 2,4,8,16,12,14,18,26,22,24,28
echo implode(',',arrayBuilder(20)),"\n"; // 1,2,4,8,11,12,14,18
echo implode(',',arrayBuilder(24)),"\n"; // 1,2,4,8,11,12,14,18,21,22,24
Этот метод очень похож на ответ localheinz, но использует метод, представленный мне сок жука которая быстрее и версия php безопасна. Я только прочитал ответ localheinz как раз перед публикацией; это вопрос почти идентичной интеллектуальной конвергенции. Я просто удовлетворяю резюме лучшими методами, которые я могу придумать.
Как / почему это работает без поискового массива или операторов if?
arrayBuilder()
, вы должны отправить $max
значение (представляющее максимально возможное значение в возвращаемом массиве) и, необязательно, вы можете назначить $num
(первое число в возвращаемом массиве) в противном случае значение по умолчанию 1
,arrayBuilder()
, $array
объявлен как пустой массив. Это важно, если входные значения пользователя не допускают ни одной итерации в for
петля. Эта строка кода важна для правильной практики кодирования, чтобы гарантировать, что ни при каких обстоятельствах не должно происходить Уведомление / Предупреждение / Ошибка.for
цикл является самым сложным циклом в PHP (так говорит руководство), и его три выражения являются идеальным способом упаковки техник, которые я использую.
$i=0;
это то, что php разработчики видят все время. Это разовая декларация $i
сравнявшись 0
который только происходит before
первая итерация.before
каждая итерация Я постараюсь разбить его: (круглые скобки имеют жизненно важное значение для этого выражения, чтобы избежать непредвиденных результатов из-за приоритет оператора
(
открывающая скобка содержит левую сторону оператора сравнения$val=
объявлять $val
для использования внутри цикла на каждой итерации($num<<$i%4)
из-за приоритета это так же, как $num<<($i%4)
значение: «найти остаток от $i
делится на 4, затем используйте побитовый оператор «сдвиг влево» чтобы умножить $num
от 2
за каждый «остаток». Это очень быстрый способ достижения четырехзначного [don't double],[double once],[double twice],[double three times]
создавать: 1,2,4,8
, 2,4,8,16
, и так далее. bitwise operators
всегда более эффективны, чем arithmetic operators
,+
добавить (не объединение в случае путаницы)10*floor($i/4)
округлить вниз $i
деленное на 4
затем умножить на 10
так что первые четыре итерации получают бонус 0
, следующие четыре получить 10
, следующие четыре получить 20
, и так далее.)
закрывающая скобка содержит левую сторону оператора сравнения<=$max
разрешить итерацию до $max
значение превышено.++$i
является предварительно инкрементацию $i
на end
каждой итерации.Комплексное решение с использованием while
цикл:
$input = 33;
$result = [1]; // result array
$k = 0; // coeficient
$n = 1;
while ($n < $input) {
$size = count($result); // current array size
if ($size < 4) { // filling 1st 4 values (i.e. 1, 2, 4, 8)
$n += $n;
$result[] = $n;
}
if ($size % 4 == 0) { // determining each 4-values sequence
$multiplier = 10 * ++$k;
}
if ($size >= 4) {
$n = $multiplier + $result[$size - (4 * $k)];
if ($n >= $input) {
break;
}
$result[] = $n;
}
}
print_r($result);
Выход:
Array
(
[0] => 1
[1] => 2
[2] => 4
[3] => 8
[4] => 11
[5] => 12
[6] => 14
[7] => 18
[8] => 21
[9] => 22
[10] => 24
[11] => 28
[12] => 31
[13] => 32
)
При ближайшем рассмотрении каждое значение в последовательности значений, которые вы хотите, может быть рассчитано путем добавления соответствующих значений двух последовательностей.
0 0 0 0 10 10 10 10 20 20 20 20
1 2 4 8 1 2 4 8 1 2 4 8
1 2 4 8 11 12 14 18 21 22 24 28
Индекс последовательностей начинается с 0
, Кроме того, они могли бы начать с 1
, но тогда мы должны были бы вычесть 1
так что для простоты начнем с 0
,
$a = 10 * floor($n / 4);
Функция floor()
принимает числовое значение и обрезает дробь.
Также см https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.
$b = 2 ** ($n % 4);
Оператор **
сочетает в себе база с показатель степени и вычисляет результат поднятия база в силу показатель степени.
В версиях PHP до PHP 5.6 вам придется прибегнуть к использованию pow()
, увидеть http://php.net/manual/en/function.pow.php.
Оператор %
объединяет два значения и вычисляет остаток от деления первого на второе.
$value = $a + $b;
$input = 20;
// sequence a
$a = function ($n) {
return 10 * floor($n / 4);
};
// sequence b
$b = function ($n) {
return 2 ** ($n % 4);
};
// collect values in an array
$values = [];
// use a for loop, stop looping when value is greater than input
for ($n = 0; $input >= $value = $a($n) + $b($n) ; ++$n) {
$values[] = $value;
}
echo implode(' ', $values);
Для справки смотрите:
Например, смотрите: