如何递归地将两个正整数相乘而不使用*运算符(或/运算符)? 。您可以使用加法,减法和位移

时间:2018-04-15 07:36:03

标签: python algorithm recursion dynamic-programming

我偶然发现了这个解决方案,但我无法理解究竟发生了什么。有人可以解释一下!

根据我的理解,它试图通过计算一半细胞然后加倍来计算a * b网格中的细胞数。但我无法理解递归调用。

请不要提出其他解决方案,请尝试解释这个解决方案:)

def minProduct(a,b):
    bigger = b if a < b else a #a < b ? b : a
    smaller = a if a < b else b #a < b ? a : b
    return minProductHelper(smaller,bigger)

def minProductHelper(smaller, bigger):
    if smaller == 0:
        return 0
    elif smaller == 1:
        return bigger

    # Compute half. If uneven, compute other half. If even, double it
    s = smaller >> 1 # divide by 2
    side1 = minProduct(s,bigger)
    side2 = side1
    if smaller % 2 == 1:
        side2 = minProductHelper(smaller - s, bigger)

    return side1 + side2

print(minProduct(5,6))

2 个答案:

答案 0 :(得分:1)

从某种意义上说,这是一种递归的分而治之算法。 1左移位有效地将数字除以2(丢弃任何余数)。 minProductHelper使用smaller2除以s = smaller >> 1,然后返回递归导出的s * bigger(smaller - s) * bigger之和。由于加法和乘法的属性,你有((smaller - s) * bigger) + (s * bigger) == smaller * bigger这是你想要的结果。您有两个基本情况,即smaller01,因此您可以想象对minProduct(a,b)的调用将继续a或{ {1}}成为一半(并将那两半分成两半),直到所有必须做的是总结一堆涉及b和一些数字或0和一些数字的产品,这可能是无需使用1运算符即可确定。较小的数字总是减少一半而不是较大的数字,因为这样可以通过较少的递归调用来达到基本情况。

答案 1 :(得分:0)

假设您将5和6相乘。然后程序首先计算出最小的数字,即5.然后通过将最小的数字除以两个完整的部分(几乎相等)来调用自身。

minProduct(5,6)=minProduct(2,5)+minProduct(3,6)。然后将minProduct(2,6)计算为minProduct(1,6)+minProduct(1,6)。既然较小的数字是1,程序只返回6并且计算出值。这发生在每个函数调用中。

minProduct(5,6) =minProduct(2,5)+minProduct(3,6) =minProduct(1,6)+minProduct(1,6)+minProduct(3,6) (Let minProduct(3,6)=18) for cohesion) =6+6+18 =30

为什么要先找出最小的数字?  之前的答案正是为什么使用较小的数字而不是较大的数字。取两个任意数字2和1000.我需要弄清楚2 * 1000是什么。然后更容易找出1000 + 1000(2 + 2 + ... + 2)。较少的函数调用意味着更快的算法。

为什么minProduct(0,a)有条件? 你确实看到了为什么有minProduct(1,a)的条件。但是minProduct(0,a)有一个条件,因为有一个特殊情况乘以2.当你调用minProduct(2,3)时。这解析为minProduct(2,3)和minProduct(0,3)。所以你需要单独处理它。