C# 递归函数中的随机跳跃
我编写了一个递归函数,它在迷宫/隧道中行走,条件是不能将同一块瓷砖移回去(如果没有剩余的瓷砖可以移动),函数返回。一切似乎都在运行,但在C# 递归函数中的随机跳跃,c#,recursion,C#,Recursion,我编写了一个递归函数,它在迷宫/隧道中行走,条件是不能将同一块瓷砖移回去(如果没有剩余的瓷砖可以移动),函数返回。一切似乎都在运行,但在返回后结束部分无原因再次调用函数。另外,int[,]beenThere将在代码中进一步使用,因此需要按原样返回 static public void Movement(int x,int y, int[,] coords, ref int[,] beenThere) { string bin = Convert.ToString(coo
返回后结束代码>部分无原因再次调用函数。另外,int[,]beenThere
将在代码中进一步使用,因此需要按原样返回
static public void Movement(int x,int y, int[,] coords, ref int[,] beenThere)
{
string bin = Convert.ToString(coords[x, y], 2).PadLeft(4, '0');
beenThere[x, y] = 1;
if (bin[0] == '0') // Bottom tile open
{
if(beenThere[x,y+1] == 0)
{
y++;
Movement(x, y, coords, ref beenThere);
}
}
if (bin[1] == '0') // Right tile open
{
if (beenThere[x + 1, y] == 0)
{
x++;
Movement(x, y, coords, ref beenThere);
}
}
if (bin[2] == '0') // Top tile open
{
if (beenThere[x, y - 1] == 0)
{
y--;
Movement(x, y, coords, ref beenThere);
}
}
if (bin[3] == '0') // Left tile open
{
if (beenThere[x - 1, y] == 0)
{
x--;
Movement(x, y, coords, ref beenThere);
}
}
// No tiles open, return back;
Console.WriteLine("End of the tunnel.");
return; // HERE LINE 12 OF CODE SNIPPET (CALLING THE FUNCTION) IS BEING RUN
}
我试着一步一步地调试,发现当满足结束条件时,通过return之后代码>部分,程序跳转到代码段的第12行
(再次调用相同的函数,即使它必须返回)。原因是什么?如何修复它?这是一个递归函数,因此,正如您所知,该函数会调用自身。但是函数调用本身不会导致该函数停止执行并“转到”新函数。因此,与任何其他代码一样,在函数返回后,代码继续执行。与任何其他代码一样:
public void DoStuff() {
Console.WriteLine("Stuff");
}
public void Main() {
Console.WriteLine("Before Stuff");
DoStuff(); //control flow enters "DoStuff"
//once DoStuff returns, code continues as normal - it's the same in recursion!
Console.WriteLine("After Stuff");
}
只要用递归调用替换DoStuff()
,就完全一样了
简而言之:添加return调用移动(…)后的code>s每个条件下的代码>。这是一个递归函数,因此函数会调用自身,正如您所知。但是函数调用本身不会导致该函数停止执行并“转到”新函数。因此,与任何其他代码一样,在函数返回后,代码继续执行。与任何其他代码一样:
public void DoStuff() {
Console.WriteLine("Stuff");
}
public void Main() {
Console.WriteLine("Before Stuff");
DoStuff(); //control flow enters "DoStuff"
//once DoStuff returns, code continues as normal - it's the same in recursion!
Console.WriteLine("After Stuff");
}
只要用递归调用替换DoStuff()
,就完全一样了
简而言之:添加return调用移动(…)后的code>s代码>在每种情况下。您确定它不仅仅返回给调用者吗?因为这个函数是递归的,所以它很容易看起来像是在重复它自己。这就是递归
的工作原理。每个递归步骤都将在返回后继续,以命中返回。你确定你需要退货吗?似乎无缘无故地使您的代码更加复杂。//没有打开的平铺,请返回代码>-->否,每次调用Movement()都会到达此代码,因为没有代码路径会导致函数在到达该点之前中止!这就是函数调用的工作方式。一个函数A调用另一个函数B。一旦B完成,控制返回到A,并在停止的地方继续。这是正常的,也是预期的。您确定这不仅仅是返回给来电者吗?因为这个函数是递归的,所以它很容易看起来像是在重复它自己。这就是递归
的工作原理。每个递归步骤都将在返回后继续,以命中返回。你确定你需要退货吗?似乎无缘无故地使您的代码更加复杂。//没有打开的平铺,请返回代码>-->否,每次调用Movement()都会到达此代码,因为没有代码路径会导致函数在到达该点之前中止!这就是函数调用的工作方式。一个函数A调用另一个函数B。一旦B完成,控制返回到A,并在停止的地方继续。这是正常的,也是意料之中的。这是有道理的,我对递归很陌生,谢谢!这很有道理,我对递归很陌生,谢谢!