另一个 FizzBu​​zz 解决方案

Another FizzBuzz solution

我正在参加工作面试,被要求用 PHP 解决 FizzBu​​zz。

Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.

我以前从未听说过 FizzBu​​zz,但这是我解决它的方法,因为我不知道模数或如何使用它。:

for ($i = 1; $i <= 100; $i++){
   if($i / 3 == round($i / 3) && $i / 5 == round($i / 5)){
      echo $i . " is FizzBuzz<br />";
   }
   else if($i / 3 == round($i / 3)){
      echo $i . " is Fizz<br />";
   }
   else if($i / 5 == round($i / 5)){
      echo $i . " is Buzz<br />";
   }
   else {
      echo $i."<br />";
   }
}

我用谷歌搜索并没有找到任何解决方案,这让我想到它可能有问题,这是我发现的接近我的解决方案之一:

for ($i = 1; $i <= 100; $i++){
   if($i % 3 == 0 && $i % 5 ==0){
      echo "FizzBuzz<br />";
   }
   else if($i % 3 == 0){
      echo "Fizz<br />";
   }
   else if($i % 5 == 0){
      echo "Buzz<br />";
   }
   else {
      echo $i."<br />";
   }
}

我的代码工作正常,但它有什么我没发现的问题吗?

实际上他们是在测试你如何解决这么简单的任务。它应该得到无限优化,代码应该干净易读。

你的代码版本不好。 你在网上找的那个版本比较好,但是从优化的角度来说,还不够理想。

试着思考如何用更少的行动达到目标。

一些提示:

  • 不要为此任务使用函数(例如范围)——它只会减慢脚本执行时间
  • 使用 operator "for" 这个任务,不要使用任何其他的(while, do-while, foreach),因为 operator "for" 最适合这种情况(你知道多少次迭代你需要)。
  • 不要使用舍入函数,使用取模运算符“%”,因为任何函数都比任何运算符运行得慢
  • 在结果中你需要得到代码,其中的操作次数会尽可能少("if"语句的数量,像“==”这样的运算符的数量" 或 "%"

    • 使用 15 而不是 % 3 && % 5 - 更少的计算 - 更快的执行时间。

我的代码示例:

for ($i = 1; $i <= 100; $i++) {
    if ($i % 15 == 0) {
        echo 'FizzBuzz<br>';
    } elseif ($i % 3 == 0) {
        echo 'Fizz<br>';
    } elseif ($i % 5 == 0) {
        echo 'Buzz<br>';
    } else {
        echo $i . '<br>';
    }
}

如果你仔细阅读,上面写着“instead”。

这是 FizzBu​​zz 问题的另一个简短而干净的解决方案:

foreach (range(1, 100) as $number) {
    if(0 !== $number % 3 && 0 !== $number % 5) {
        echo $number.'<br>';
        continue;
    }

    if(0 === $number % 3) {
        echo 'Fizz';
    }

    if(0 === $number % 5) {
        echo 'Buzz';
    }

    echo '<br>';
}

输出是:

1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16

代码风格和缺乏优化给面试官留下了新手的印象。我的建议是:

  • 关注PSR-2
  • 从不使用else(重组,早点使用returns/continues)
  • 始终尝试减少 if 的数量(代码复杂度)
  • 在处理整数和空值(以及任何其他类型)时使用 "identical" 运算符进行比较
  • 如果从未提及 HTML,请不要使用 <br/>
  • 尽量保持可维护性:
    • 提取 variables/functions 中的匹配计算,以便轻松更改它们
    • 不要过于复杂。
  • 尝试数学优化:
    • 使用 %15 代替 %3 和 %5 检查
    • 您也可以完全跳过上面的内容(检查 %15),因为您已经计算过了。布尔运算要快得多。
    • 尽量不要计算两次。

恕我直言,要遵循所有良好做法,您的代码应如下所示:

for ($i = 1; $i <= 100; $i++) {
    $isFizz = (0 === $i % 3);
    $isBuzz = (0 === $i % 5);

    if (!$isFizz && !$isBuzz) {
        echo $i . PHP_EOL;

        continue;
    }

    if ($isFizz) {
        echo 'Fizz';
    }

    if ($isBuzz) {
        echo 'Buzz';
    }

    echo PHP_EOL;
}

Test

还有一个棘手的解决方案

for ($i = 1; $i <= 100; $i++) {
    switch ($i % 15) {
        case 3:
        case 6:
        case 9:
            echo 'Fizz';
            break;
        case 5:
        case 10:
            echo 'Buzz';
            break;
        case 0:
            echo 'FizzBuzz';
            break;
        default:
            echo $i;
            break;
    }

    echo PHP_EOL;
}