Pow(x,y) 函数的工作流程是什么?
What is the workflow of Pow(x,y) function?
我正在学习 "sololearn" 和 udemy 课程以尝试学习 C#。我正在做挑战,但无法弄清楚下面的代码是如何得到 32 的(因为 32 是这里的正确答案,我试图找出原因)。有人可以给我解释一下这个过程吗,我认为调用自身的方法正在抛出我。
static double Pow(double x, int y)
{
if (y == 0)
{
return 1.0;
}
else
{
return x * Pow(x, y - 1);
}
}
static void Main()
{
Console.Write(Pow(2, 5));
}
请原谅我糟糕的编码。我想在手机上做,这很难,答案是 32。有人可以解释为什么吗?
编辑:在此表示歉意,这是我的工作方式。将 2 和 5 传递给 Pow,检查 y == 0
是否为假,现在是 y == 5
,因此 x * pow(x, y-1)
公式将处于活动状态。 X 仍然是 2,y 现在是 4,这意味着它再次检查它是否等于 0 失败,这个循环继续直到它 returns 1.0,x 保持在 2 所以 2 * 1.0 = 2
而不是 32?
好的,让我们回顾一下整个过程。
首先,静态函数是不需要实例化对象就可以调用的函数。同一 class 的所有对象共享一个签名。 double 是 C# 中的一种类型,它出现在这里是为了显示函数的最终输出类型。 Pow 是函数的名称,double x, int y 是按类型描述的参数(名称不太好,但我们将在另一天保留)
所以 x 是一个数,y 是该数的幂。这里有一个条件来检查两个结果。如果 y 是 0 那么答案总是 1,简单的数学。否则,该函数将使用递归执行算术运算(它会再次调用自身,直到满足终止条件)。我们得到 32 的原因是因为 2x2x2x2x2 = 32。它是 2 的 5 次方。
我假设您知道 main 和 console.write 是什么。
首先要注意的是,这不是您通常实现幂函数的方式。这样做是为了演示递归。
说完这些,让我们看看调用 Pow(2, 5)
:
时会发生什么
Pow(x = 2, y = 5)
-> return 2 * Pow(2, 4)
<- 2 * 16 = 32
Pow(x = 2, y = 4)
-> return 2 * Pow(2, 3)
<- 2 * 8 = 16
Pow(x = 2, y = 3)
-> return 2 * Pow(2, 2)
<- 2 * 4 = 8
Pow(x = 2, y = 2)
-> return 2 * Pow(2, 1)
<- 2 * 2 = 4
Pow(x = 2, y = 1)
-> return 2 * Pow(2, 0)
<- 2 * 1 = 2
Pow(x = 2, y = 0)
-> return 1 (because y == 0)
<- 1
要阅读此递归调用堆栈的表示,请从上到下查看参数如何变化;然后从底部向上看 return 值(我用 <-
表示)。
该方法基本上计算“x
的 y
次方”。它以 递归 方式执行此操作。
首先,它定义了一个基本情况:任何事物的 0 次方都是 1。
然后,它定义了在所有其他情况下要做什么:x * Pow(x, y - 1)
。假设 y
很大,那么 x * Pow(x, y - 1)
是多少?它是 x * x * Pow(x, y - 2)
,它又是 x * x * x * Pow(x, y - 3)
。看到这里的模式了吗?最终,您将到达第二个参数 y - N
为 0 的位置,正如我们已经确定的那样,它为 1。此时,我们得到了多少 x *
?正好 y
.
让我们看看 Pow(2, 5)
的实际效果:
Pow(2, 5)
2 * Pow(2, 4)
2 * 2 * Pow(2, 3)
2 * 2 * 2 * Pow(2, 2)
2 * 2 * 2 * 2 * Pow(2, 1)
2 * 2 * 2 * 2 * 2 * Pow(2, 0)
2 * 2 * 2 * 2 * 2 * 1
因此结果是 32。
你好它的递归,它重复直到 y=1
,然后 return 2
,然后 return 4, 8, 16, 32
然后结束。 2^5=32
为了能够理解此递归行为中的每个操作,请记录所有详细信息以查看实际发生的情况。 如:
using System;
namespace Tester
{
class test
{
// What Pow actually does:
static double logPow(double x, int y) {
var old = x; // Hold the x
for (var i = 0; i < y; i++){ // do it y times
x = old * x; // Multiply with it's first self
}
return x;
}
static int counter = 0;
static double Pow(double x, int y) {
counter++;
Console.Write("Recursive action[" + counter + "] Y status ["+ y +"] : ");
if (y == 0)
{
Console.Write("return 1.0 = " + logPow(x, y) + " \n");
return 1.0;
}
else
{
Console.Write("return " + x + " * Pow(" + x + ", " + y + " - 1) = " + logPow(x,y-1) + " \n");
return x * Pow(x, y - 1);
}
}
static void Main() {
Console.Write("Last Result : " + Pow(2, 5));
}
}
}
给出结果:
Recursive action[1] Y status [5] : return 2 * Pow(2, 5 - 1) = 32
Recursive action[2] Y status [4] : return 2 * Pow(2, 4 - 1) = 16
Recursive action[3] Y status [3] : return 2 * Pow(2, 3 - 1) = 8
Recursive action[4] Y status [2] : return 2 * Pow(2, 2 - 1) = 4
Recursive action[5] Y status [1] : return 2 * Pow(2, 1 - 1) = 2
Recursive action[6] Y status [0] : return 1.0 = 2
Last Result : 32
您可以通过查看这些详细信息来调试您的代码。
你也可以使用这个 link 来玩得开心:https://onlinegdb.com/Bysbxat9H
我正在学习 "sololearn" 和 udemy 课程以尝试学习 C#。我正在做挑战,但无法弄清楚下面的代码是如何得到 32 的(因为 32 是这里的正确答案,我试图找出原因)。有人可以给我解释一下这个过程吗,我认为调用自身的方法正在抛出我。
static double Pow(double x, int y)
{
if (y == 0)
{
return 1.0;
}
else
{
return x * Pow(x, y - 1);
}
}
static void Main()
{
Console.Write(Pow(2, 5));
}
请原谅我糟糕的编码。我想在手机上做,这很难,答案是 32。有人可以解释为什么吗?
编辑:在此表示歉意,这是我的工作方式。将 2 和 5 传递给 Pow,检查 y == 0
是否为假,现在是 y == 5
,因此 x * pow(x, y-1)
公式将处于活动状态。 X 仍然是 2,y 现在是 4,这意味着它再次检查它是否等于 0 失败,这个循环继续直到它 returns 1.0,x 保持在 2 所以 2 * 1.0 = 2
而不是 32?
好的,让我们回顾一下整个过程。
首先,静态函数是不需要实例化对象就可以调用的函数。同一 class 的所有对象共享一个签名。 double 是 C# 中的一种类型,它出现在这里是为了显示函数的最终输出类型。 Pow 是函数的名称,double x, int y 是按类型描述的参数(名称不太好,但我们将在另一天保留)
所以 x 是一个数,y 是该数的幂。这里有一个条件来检查两个结果。如果 y 是 0 那么答案总是 1,简单的数学。否则,该函数将使用递归执行算术运算(它会再次调用自身,直到满足终止条件)。我们得到 32 的原因是因为 2x2x2x2x2 = 32。它是 2 的 5 次方。
我假设您知道 main 和 console.write 是什么。
首先要注意的是,这不是您通常实现幂函数的方式。这样做是为了演示递归。
说完这些,让我们看看调用 Pow(2, 5)
:
Pow(x = 2, y = 5)
-> return 2 * Pow(2, 4)
<- 2 * 16 = 32
Pow(x = 2, y = 4)
-> return 2 * Pow(2, 3)
<- 2 * 8 = 16
Pow(x = 2, y = 3)
-> return 2 * Pow(2, 2)
<- 2 * 4 = 8
Pow(x = 2, y = 2)
-> return 2 * Pow(2, 1)
<- 2 * 2 = 4
Pow(x = 2, y = 1)
-> return 2 * Pow(2, 0)
<- 2 * 1 = 2
Pow(x = 2, y = 0)
-> return 1 (because y == 0)
<- 1
要阅读此递归调用堆栈的表示,请从上到下查看参数如何变化;然后从底部向上看 return 值(我用 <-
表示)。
该方法基本上计算“x
的 y
次方”。它以 递归 方式执行此操作。
首先,它定义了一个基本情况:任何事物的 0 次方都是 1。
然后,它定义了在所有其他情况下要做什么:x * Pow(x, y - 1)
。假设 y
很大,那么 x * Pow(x, y - 1)
是多少?它是 x * x * Pow(x, y - 2)
,它又是 x * x * x * Pow(x, y - 3)
。看到这里的模式了吗?最终,您将到达第二个参数 y - N
为 0 的位置,正如我们已经确定的那样,它为 1。此时,我们得到了多少 x *
?正好 y
.
让我们看看 Pow(2, 5)
的实际效果:
Pow(2, 5)
2 * Pow(2, 4)
2 * 2 * Pow(2, 3)
2 * 2 * 2 * Pow(2, 2)
2 * 2 * 2 * 2 * Pow(2, 1)
2 * 2 * 2 * 2 * 2 * Pow(2, 0)
2 * 2 * 2 * 2 * 2 * 1
因此结果是 32。
你好它的递归,它重复直到 y=1
,然后 return 2
,然后 return 4, 8, 16, 32
然后结束。 2^5=32
为了能够理解此递归行为中的每个操作,请记录所有详细信息以查看实际发生的情况。 如:
using System;
namespace Tester
{
class test
{
// What Pow actually does:
static double logPow(double x, int y) {
var old = x; // Hold the x
for (var i = 0; i < y; i++){ // do it y times
x = old * x; // Multiply with it's first self
}
return x;
}
static int counter = 0;
static double Pow(double x, int y) {
counter++;
Console.Write("Recursive action[" + counter + "] Y status ["+ y +"] : ");
if (y == 0)
{
Console.Write("return 1.0 = " + logPow(x, y) + " \n");
return 1.0;
}
else
{
Console.Write("return " + x + " * Pow(" + x + ", " + y + " - 1) = " + logPow(x,y-1) + " \n");
return x * Pow(x, y - 1);
}
}
static void Main() {
Console.Write("Last Result : " + Pow(2, 5));
}
}
}
给出结果:
Recursive action[1] Y status [5] : return 2 * Pow(2, 5 - 1) = 32
Recursive action[2] Y status [4] : return 2 * Pow(2, 4 - 1) = 16
Recursive action[3] Y status [3] : return 2 * Pow(2, 3 - 1) = 8
Recursive action[4] Y status [2] : return 2 * Pow(2, 2 - 1) = 4
Recursive action[5] Y status [1] : return 2 * Pow(2, 1 - 1) = 2
Recursive action[6] Y status [0] : return 1.0 = 2
Last Result : 32
您可以通过查看这些详细信息来调试您的代码。 你也可以使用这个 link 来玩得开心:https://onlinegdb.com/Bysbxat9H