递归乘法方法

时间:2014-05-03 00:35:57

标签: c# algorithm recursion

我跟随此http://www.cs.berkeley.edu/~vazirani/algorithms/chap1.pdf(第24页底部)。在书中,作者描述了Al Khwarizmi乘法算法。这是我的实现

static int RecMultiply(int x, int y)
{
    if (y == 0)
        return 0;
    int z = RecMultiply(x, y / 2);
    if (y % 2 == 0)
        return 2 * z;
    else
        return x + 2 * z;
}

我已经完成了几次代码,我只是没有理解它。为什么底部将x添加到2 * z?在我看来,z既可用作跑步总数,也可用作"右列"书中算法中的数字。有人可以打破这段代码并解释一下吗?

2 个答案:

答案 0 :(得分:3)

这很简单。

Z是通过乘以x和y的一半来计算的。

如果y是偶数奇偶校验(如果是部分)则返回2 * z = 2 * x * y / 2 = x * y(这是原始请求)

如果y是奇数奇偶校验(否则为部分),则返回2 * z + x。我们为什么要加x?那是因为y / 2对于偶数和跟随奇数是相同的。所以Z会是一样的。但是,如果这个if部分我们检测它是奇数还是偶数,如果是奇数,我们再次将x加到结果中。

答案 1 :(得分:3)

由于乘法是简单的重复加法,如果y是对,则可以将其除以2,并将x乘以2。 (所以,2 * 2 = 2 + 2.2 * 3 = 2 + 2 + 2,2 * 4 = 2 + 2 + 2 + 2 ....)
如果y为奇数,则可以减去1,得到一对y,并且需要添加x,(基本上是1 * y)。

这是一个细分:

RecMultiply(5,5) :
+-  z = RecMultiply(5,2)
|   return 5 + 2 * z (=20 +5 =25)
|
|
+-- RecMultiply(5,2) :
    +-  z = RecMultiply(5,1)
    |   return 2 * z (=10)
    |
    +-- RecMultiply(5,1) :
        +-  z = RecMultiply(5,0)
        |   return 5 + 0
        |
        +---RecMultiply(5,0) :
            return 0

RecMultiply(5,4) :
+-  z = RecMultiply(5,2)
|   return 2 * z (=)
|
+-- RecMultiply(5,2) :
        +-  z = RecMultiply(5,1)
        |   return 2 * z (=10)
        |
        +-- RecMultiply(5,1) :
            +-  z = RecMultiply(5,0)
            |   return 5 + 0
            |
            +---RecMultiply(5,0) :
                return 0

所以,基本上,在递归位(负责所有对乘法)之后,您可能需要添加另一个y,在上面的第一种情况下,对于第一个5呼叫)。

请注意y=1的特殊情况,这意味着x*1在我们的案例中显然是5。同样的逻辑适用。

如果有帮助,您可能希望这样看:

static int RecMultiply(int x, int y)
{

    switch (y)
    {
        case 0:
            return 0;
            break;

        case 1:
            return x;
            break;

        default:
            return (y%2 ==0) ? RecMultiply(x, y/2)
                             : x + RecMultiply(x, y/2);
            break;
    } 
}

我认为它以更容易理解的方式表示+1(或奇数情况)。