【问题标题】:Time efficiency of the Russian peasant multiplication algorithm俄罗斯农民乘法算法的时间效率
【发布时间】:2019-02-21 07:27:56
【问题描述】:

从时间效率的角度来看,Russian peasant multiplication算法是用n乘m还是m乘n有关系吗?

比如,计算26*47时,时间效率和计算47*26差不多吗?

【问题讨论】:

    标签: algorithm language-agnostic


    【解决方案1】:

    由于算法运行floor(log2(k)) 迭代以获取k 的乘数(第一个数字),因此运行时间肯定取决于顺序。如果nm 位于相同的两个连续两个幂之间,那么它们将需要相同数量的迭代来完成。否则,请始终将较小的数字放在第一位,以最大限度地减少运行时间。

    【讨论】:

      【解决方案2】:
      unsigned int russianPeasant(unsigned int a, unsigned int b) { 
          int res = 0;  // initialize result 
          // While second number doesn't become 1 
          while (b > 0) 
          { 
               // If second number becomes odd, add the first number to result 
               if (b & 1) 
                   res = res + a; 
               // Double the first number and halve the second number 
               a = a << 1; 
               b = b >> 1; 
           } 
           return res; 
      }
      

      算法在b变为0时退出while循环。循环运行的次数为[log2(b)] + 1次。

      而且移位几乎需要恒定的时间(1 个 CPU 周期)

      使用较小的值作为 b 调用是有意义的。

      奖励:速度比较

      我编写了上面的代码,并在循环中运行相同的数字 47 和 26 10**8 次。

      a = 26, b=47,平均耗时 1336852.2 微秒。

      a = 47, b=26,平均耗时 1094454.4 微秒。

      有趣的旁注:

      尽管正如@Dillon Davis 提到的,如果它们的日志相同,它应该需要相同数量的迭代,但我发现它仍然需要更少的时间,因为 b 的数量较小。

      (所有时间以微秒为单位)
      a = 46,b = 36 - 1204240.6
      a = 36, b = 46 - 1295766.8

      a= 44, b = 36 - 1204266.2
      a= 36,b = 44 - 1253821.17。

      TLDR: 以较小的第二个数字运行(while 循环中的那个)

      源码来自:https://www.geeksforgeeks.org/russian-peasant-multiply-two-numbers-using-bitwise-operators/

      【讨论】:

        【解决方案3】:

        这取决于您如何实现俄罗斯农民算法。可以是:

        • a*b 更快
        • b*a 更快
        • 没有区别

        我选择没有区别,因为实数的数学乘法是可交换的:a*b=b*a 并且因为最终用户在调用您的函数时不喜欢关心参数的顺序

        为此,您需要调整您的代码,例如:

        Let the two given numbers be 'a' and 'b'.
        1) If 'b' is greater than 'a' - swap 'a' with 'b'
        2) Initialize result 'res' as 0.
        3) Do following while 'b' is greater than 0
           a) If 'b' is odd, add 'a' to 'res'
           b) Double 'a' and halve 'b'
        4) Return 'res'.
        

        这段代码会很复杂

        O(log₂(min(a,b)))

        【讨论】:

          猜你喜欢
          • 2010-09-20
          • 2013-01-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多