【问题标题】:Make an output of 1 2 4 8 11 12 14 18... using one for loop使用一个 for 循环输出 1 2 4 8 11 12 14 18...
【发布时间】:2018-02-11 23:36:54
【问题描述】:

如何生成类似的数字序列

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

【问题讨论】:

  • 那么您需要帮助的代码在哪里?
  • 我拥有的是这样的: 这个输出应该是:1 2 4 8 11 12 14 18 因为用户输入是 20
  • 这是一个很好的问题,它已经过编辑以反映我认为原始发帖人的问题。请考虑重新开放。
  • @localheinz 我认为您可能过于字面地解释了 OP 对“one for loop”的请求。 OP 的编码尝试(在发布后 9 分钟被评论)使用了两个单独的循环,我认为她很有可能只是想将该方法简化为一个循环。对于 OP 来说,限制所实现的循环类型可能并不重要。如果您因为这种字面解释而对任何其他答案投了反对票,我想礼貌地请您取消对唯一问题的任何答案投反对票。
  • @mickmackusa 也许原发帖人想澄清她想要什么?

标签: php arrays loops increment


【解决方案1】:

仔细观察,您想要的值序列中的每个值都可以通过将两个序列的对应值相加来计算。

序列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);

** 运算符将 baseexponent 结合起来,计算出 baseexponent 次方的结果

在 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);

参考见:

例如,请参阅:

【讨论】:

  • 改进了答案并添加了解释。这对你有用吗?
【解决方案2】:

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

【讨论】:

  • 不使用for 循环。
  • @localheinz,如果你知道循环是如何工作的,那不会有什么不同。这里主要是算法。但是,似乎 OP 根本不关心算法
  • 原始发帖人要求使用单个for 循环,您的回答未使用for 循环。
  • @localheinz,现在我看到您也不太关心算法(以及循环)。 whilefor 在这种情况下会做同样的事情。这只是文字游戏
  • 也许您应该在回答之前花更多时间阅读问题。
【解决方案3】:

代码: (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&lt;&lt;$i%4) 因为优先级,这与$num&lt;&lt;($i%4) 相同,意思是:“找到$i 的余数除以4,然后使用bitwise "shift left" operator 来“将$num 乘以2 得到每个“余数”。这是实现[don't double],[double once],[double twice],[double three times] 的4 位数模式创建:1,2,4,82,4,8,16 等的一种非常快速的方法。 bitwise operators 总是比 arithmetic operators 更有效。
        arithmetic operator modulo 的使用确保预期的核心编号模式每四次迭代重复一次。
      • +add(不要串联,以免混淆)
      • 10*floor($i/4) 向下舍入 $i 除以 4 然后乘以 10,这样前四次迭代得到 0,接下来的四次得到 10,接下来的四次得到 20,和以此类推。
      • ) 右括号包含比较运算符的左侧
      • &lt;=$max 允许迭代直到超过 $max 值。
    • ++$ipre-incrementing $i 在每次迭代的end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-04
    • 2021-05-30
    • 2019-01-11
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多