输出1 2 4 8 11 12 14 18 ...使用一个for循环

时间:2017-09-03 15:38:07

标签: php arrays loops increment

如何生成像

这样的数字序列
  

1 2 4 8 11 12 14 18 ...

(每4个数字加10)并满足以下附加要求:

  • 仅使用一个循环
  • 当序列中的值大于指定的输入
  • 时,输出应该停止

实施例

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

3 个答案:

答案 0 :(得分:0)

代码:Demo

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的答案非常相似,但是使用beetlejuice向我介绍的技术,它更快且php版本安全。我只是在张贴之前阅读了localheinz的回答;这是一个几乎相同的智力趋同问题。我只是用我能想到的最佳方法来满足简报。

如果没有查找数组或if语句,如何/为什么这样做?

  • 当您致电arrayBuilder()时,您必须发送$max值(表示返回数组中可能的最高值),并且您可以选择$num(第一个数字)返回数组)否则默认值为1
  • arrayBuilder()内,$array被声明为空数组。如果用户的输入值不允许在for循环中进行单次迭代,则这很重要。这行代码对于良好的编码实践至关重要,以确保在任何情况下都不应发生通知/警告/错误。
  • for循环是php中最复杂的循环(所以说the manual),它的三个表达式是打包我使用的技术的完美方式。
    • 第一个表达式$i=0;是php开发人员一直看到的东西。它是$i等于0的一次性声明,仅在第一次迭代时before出现。
    • 第二个表达式是我整个代码块中唯一的棘手/魔法方面。每次迭代都会将此表达式称为before。我将尝试将其分解:(括号对于此表达式至关重要,以避免因operator precedence而导致的意外结果
      • (左括号以包含比较运算符的左侧
      • $val=声明$val在每次迭代中使用循环
      • ($num<<$i%4)因为优先级与$num<<($i%4)相同,意思是:“找到$i的余数除以4,然后使用bitwise "shift left" operator来”乘以{{1 } $num为每个“余数”。这是实现2的4个数字模式以创建:[don't double],[double once],[double twice],[double three times]1,2,4,8等非常快捷的方式。 2,4,8,16总是比bitwise operators更有效。
        使用arithmetic operator modulo可确保每四次迭代重复预期的核心数字模式。
      • arithmetic operators添加(如果有任何混淆,则不连接)
      • +向下舍入10*floor($i/4)除以$i然后乘以4,以便前四次迭代获得10的奖励,接下来的四次获得0,接下来的四个获得10,依此类推。
      • 20右括号,包含比较运算符的左侧
      • )允许迭代,直到超出<=$max值。
    • $max在每次迭代的++$i都是pre-incrementing $i

答案 1 :(得分:-1)

使用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
)

答案 2 :(得分:-2)

仔细观察,可以通过添加两个序列的相应值来计算所需值序列中的每个值。

序列A

 0  0  0  0 10 10 10 10 20 20 20 20

序列B

 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

$a = 10 * floor($n  / 4);

函数floor()接受数值,并将截断分数。

另见https://en.wikipedia.org/wiki/Floor_and_ceiling_functions

序列B

$b = 2 ** ($n  % 4);

运算符** base exponent 组合在一起,并计算将 base 提升为幂的结果>指数

在PHP 5.6之前的PHP版本中,您将不得不使用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);

供参考,见:

有关示例,请参阅: