C# 递归乘法法
我将跟随这个(第24页底部)。在这本书中,作者描述了Al-Khwarizmi乘法算法。这是我的实现C# 递归乘法法,c#,algorithm,recursion,C#,Algorithm,Recursion,我将跟随这个(第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; } 我已经过了好几次代码,我
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在书中的算法中既是一个连续的总数,也是一个“右列”数。有人能把这段代码分解并解释一下吗?很简单
Z是用x乘以y的一半来计算的
如果y是偶数奇偶校验(If段),则返回2*z=2*x*y/2=x*y(这是原始请求)
如果y是奇数奇偶校验(else部分),则返回2*z+x。为什么要加x???这是因为对于偶数和奇数之后的数字,y/2将是相同的。所以Z是一样的。但是,通过这个if部分,我们可以检测它是奇数还是偶数,如果是奇数,我们再将x加到结果中。因为乘法是简单的重复加法,如果
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(或奇数)。我想我的下一个问题是,x、y和z相对于书中的列和运行总数代表什么?我会说,忘记这本书,除非你需要遵循它。试着理解逻辑。X和y是我们需要计算的两个乘积。Z是过程中使用的临时值。+1。我想如果在代码中使用显式的
(y%2)
,而不是将其展开,y=(y/2)*2+(y%2)
那么r(x,y)=x*y=x*((y/2)*2+(y%2))=r(x,y/2)*2+x*(y%2)
可以避免对的混淆。是的,这个问题似乎包含了算法的文字实现。