【问题标题】:how can this algorithm be optimized这个算法如何优化
【发布时间】:2014-03-08 05:36:39
【问题描述】:

我试图找到能被 1 到 20 的所有数字整除的最小正数,代码如下:

$num = 2520;
$x = 1;

while($x < 21){
    if($num % $x == 0){
        $x++;
    }else{
        $num += 20;
        $x = 1;
    }
}

echo $num;

它会在不到 1 分钟的时间内给出正确的输出。这个执行时间在专业领域很糟糕吗?有什么办法可以优化吗?

附:我从 2520 开始,因为它是可以除以 1 到 10 的每个数字而没有任何余数的最小数字。

【问题讨论】:

  • 你不需要这个程序,它是 2^4*3^2*5*7*11*13*17*19。它是在不超过 20 的情况下将所有素数提高到尽可能大的幂的乘积。

标签: php algorithm


【解决方案1】:

建议:求[1,20]中所有整数的素数。

例如,我们有素数 {2,3,5,7,11,13,17,19}。所以,如果解是可整除的 被 [1,20] 中的所有整数,那么它肯定可以被这个中的每个元素整除 素数列表。所以,至少,我们的解是 >= 2*3*5*7*11*13*17*19,对吧?

现在的问题是我们在构建候选解决方案方面能有多聪明 大于那个数。好吧,我们先看看解决了多少……

2*3*5*7*11*13*17*19 能被 4 整除吗?不,所以,让我们乘以 2 得到 2*2*3*5*7*11*13*17*19,肯定能被2*2整除……

2*2*3*5*7*11*13*17*19 能被 6 整除吗?是的。

2*2*3*5*7*11*13*17*19 能被 8 整除吗? ....

你明白了。虽然我不确定,但我相信这种方法会 得出正确的答案——即能被每个整数整除的最小整数 [1,20] 中的整数。

【讨论】:

    【解决方案2】:

    使用改良的埃拉托色尼筛法进行大规模加速

    1.int ix[20]={1,2,3,4,...20};

    2.现在写一个循环

    • 您将在其中递增所有 ix[i]+=i+1;其中 i=
    • 当 ix[i]>=ix[19]
    • 如果最后所有 ix[i] 都相同,那么它的内容就是结果,所以停止/返回任何内容

    3.如果不是,则也增加 ix[19]+=20;

    • 并继续循环第 2 条

    [注释]

    • 可以轻松更改为能被任何数字整除,而不仅仅是能被 1..20 整除

    【讨论】:

      【解决方案3】:

      这听起来像Project Euler's Problem 5

      我们在这里找到的是数字 1 到 20 的 least common multiple。您可以通过 greatest common divisor 的帮助找到它:

      function gcd($a, $b) {
          if ($a == 0) return $b;
          return gcd($b % $a, $a);
      }
      
      function lcm($a, $b) {
          return $a * $b / gcd($a, $b);
      }
      
      function smallestDiv($n) {
          $div = 1;
          for ($i = 1; $i <= $n; $i++) {
              $div = lcm($div, $i);
          }
          return $div;
      }
      
      echo smallestDiv(20);
      

      请原谅我的 PHP。好久没写了。

      请注意,我们还可以通过对每个数字进行素数分解并寻找最大指数来找到答案,如hereKode Charlie's 答案中所述:

       2 = 2
       3 = 3
       4 = 2²
       5 = 5
       6 = 2 × 3
       7 = 7
       8 = 2³
       9 = 3²
      10 = 2 × 5
      11 = 11
      12 = 2² × 3
      13 = 13
      14 = 2 × 7
      15 = 3 × 5
      16 = 2⁴
      17 = 17
      18 = 2 × 3²
      19 = 19
      20 = 2² × 5
      
      lcm(1,2,…20) = 2⁴ × 3² × 5 × 7 × 11 × 13 × 17 × 19 = 232,792,560
      

      【讨论】:

        猜你喜欢
        • 2011-03-05
        • 1970-01-01
        • 1970-01-01
        • 2013-05-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-15
        • 2021-09-14
        相关资源
        最近更新 更多