C# 递归函数中的堆栈溢出异常错误
我刚开始学习c#但是我有一些java方面的经验,所以我想做的一件事是生成一个填充了1和0的2d数组映射,并递归地检查是否有一条路径,而不踩在1上 然而,在编写代码并运行它之后,它向我显示了堆栈溢出异常错误 我哪里做错了什么 编辑:数组的末尾(在本例中,最大值为9,9的单元格(它是一个10x10数组)被设置为6作为端点) 递归方法的代码:C# 递归函数中的堆栈溢出异常错误,c#,C#,我刚开始学习c#但是我有一些java方面的经验,所以我想做的一件事是生成一个填充了1和0的2d数组映射,并递归地检查是否有一条路径,而不踩在1上 然而,在编写代码并运行它之后,它向我显示了堆栈溢出异常错误 我哪里做错了什么 编辑:数组的末尾(在本例中,最大值为9,9的单元格(它是一个10x10数组)被设置为6作为端点) 递归方法的代码: public static int recursiveCheck(int[,] grid,int x, int y, int finalX, int final
public static int recursiveCheck(int[,] grid,int x, int y, int finalX, int finalY, int paths)
{
if (grid[x, y] == 6)
{
paths++;
return paths;
}
if ((grid[x + 1, y] != 1) && (x+1 < finalX))
return recursiveCheck(grid, x + 1, y, finalX, finalY, paths);
if ((grid[x, y+1] != 1) && (y+1 < finalY))
return recursiveCheck(grid, x, y+1, finalX, finalY, paths);
if ((grid[x - 1, y] != 1) && (x > 0))
return recursiveCheck(grid, x - 1, y, finalX, finalY, paths);
if (grid[x, y - 1] != 1 && y >0)
return recursiveCheck(grid, x, y - 1, finalX, finalY, paths);
return 0;
}
公共静态int递归检查(int[,]网格,int x,int y,int finalX,int finalY,int路径)
{
if(网格[x,y]==6)
{
路径++;
返回路径;
}
如果((网格[x+1,y]!=1)和&(x+10))
返回递归检查(网格,x-1,y,finalX,finalY,路径);
如果(网格[x,y-1]!=1&&y>0)
返回递归检查(网格、x、y-1、finalX、finalY、路径);
返回0;
}
阵列初始化代码:
public static int[,] gridGen()
{
int[,] grid = new int[10, 10];
Random rnd = new Random();
int lim;
for (int i = 0; i < 10; i++)
{
for (int c = 0; c < 10; c++)
{
lim = rnd.Next(0, 2);
//Console.WriteLine($"lim: {lim} ");
grid[i, c] = lim;
}
}
grid[0, 0] = 2;
grid[grid.GetLength(0) - 1, grid.GetLength(1) - 1] = 6;
for (int i = 0; i < 10; i++)
{
for (int c = 0; c < 10; c++)
{
Console.Write(grid[i, c] + " ");
}
Console.WriteLine();
}
return grid;
}
publicstaticint[,]gridGen()
{
int[,]grid=新的int[10,10];
随机rnd=新随机();
int lim;
对于(int i=0;i<10;i++)
{
对于(int c=0;c<10;c++)
{
lim=rnd.Next(0,2);
//Console.WriteLine($“lim:{lim}”);
网格[i,c]=lim;
}
}
网格[0,0]=2;
grid[grid.GetLength(0)-1,grid.GetLength(1)-1]=6;
对于(int i=0;i<10;i++)
{
对于(int c=0;c<10;c++)
{
Write(grid[i,c]+“”);
}
Console.WriteLine();
}
返回网格;
}
您没有记录您已经访问过的空间。因此,假设网格中有两个相邻的零,那么函数将在第一级递归中移动到一个,然后在第二级递归中移动到另一个,然后在第三级返回到第一个(即使第一级递归仍然在堆栈上),以此类推
有很多方法可以让你跟踪你已经访问过的地方。如果您希望在调用此方法时临时修改输入数组,可以在查看周围的空间之前,将当前所在的空间设置为1
public static int recursiveCheck(int[,] grid,int x, int y, int finalX, int finalY, int paths)
{
var originalValue = grid[x, y];
if (originalValue == 6)
{
paths++;
return paths;
}
grid[x, y] = 1; // prevent deeper recursion from coming back to this space
if ((grid[x + 1, y] != 1) && (x+1 < finalX))
return recursiveCheck(grid, x + 1, y, finalX, finalY, paths);
if ((grid[x, y+1] != 1) && (y+1 < finalY))
return recursiveCheck(grid, x, y+1, finalX, finalY, paths);
if ((grid[x - 1, y] != 1) && (x > 0))
return recursiveCheck(grid, x - 1, y, finalX, finalY, paths);
if (grid[x, y - 1] != 1 && y >0)
return recursiveCheck(grid, x, y - 1, finalX, finalY, paths);
grid[x, y] = originalValue; // allow other path checking to revisit this space.
return 0;
}
公共静态int递归检查(int[,]网格,int x,int y,int finalX,int finalY,int路径)
{
var原始值=网格[x,y];
如果(原始值==6)
{
路径++;
返回路径;
}
grid[x,y]=1;//防止更深层次的递归返回到此空间
如果((网格[x+1,y]!=1)和&(x+10))
返回递归检查(网格,x-1,y,finalX,finalY,路径);
如果(网格[x,y-1]!=1&&y>0)
返回递归检查(网格、x、y-1、finalX、finalY、路径);
grid[x,y]=originalValue;//允许其他路径检查重新访问此空间。
返回0;
}
还请注意,您可能可以通过将递归颠倒一点来简化事情:立即将边界检查和墙检查作为退出标准,并将路径数纯粹用作返回值而不是输入
public static int recursiveCheck(int[,] grid, int x, int y, int finalX, int finalY)
{
if(x < 0 || x > finalX || y < 0 || y > finalY)
{
return 0;
}
var originalValue = grid[x, y];
if (originalValue == 1)
{
return 0;
}
if (originalValue == 6)
{
return 1;
}
grid[x, y] = 1; // prevent deeper recursion from coming back to this space
var paths = recursiveCheck(grid, x + 1, y, finalX, finalY)
+ recursiveCheck(grid, x, y + 1, finalX, finalY)
+ recursiveCheck(grid, x - 1, y, finalX, finalY)
+ recursiveCheck(grid, x, y - 1, finalX, finalY);
grid[x, y] = originalValue; // allow other path checking to revisit this space.
return paths;
}
publicstaticintrecursivecheck(int[,]grid,intx,inty,intfinalx,intfinaly)
{
如果(x<0 | | x>finalX | | y<0 | | y>finalY)
{
返回0;
}
var原始值=网格[x,y];
如果(原始值==1)
{
返回0;
}
如果(原始值==6)
{
返回1;
}
grid[x,y]=1;//防止更深层次的递归返回到此空间
变量路径=递归检查(网格,x+1,y,finalX,finalY)
+递归检查(网格,x,y+1,finalX,finalY)
+递归检查(网格,x-1,y,finalX,finalY)
+递归检查(网格,x,y-1,finalX,finalY);
grid[x,y]=originalValue;//允许其他路径检查重新访问此空间。
返回路径;
}
您没有记录您已经访问过的空间。因此,假设网格中有两个相邻的零,那么函数将在第一级递归中移动到一个,然后在第二级递归中移动到另一个,然后在第三级返回到第一个(即使第一级递归仍然在堆栈上),以此类推
有很多方法可以让你跟踪你已经访问过的地方。如果您希望在调用此方法时临时修改输入数组,可以在查看周围的空间之前,将当前所在的空间设置为1
public static int recursiveCheck(int[,] grid,int x, int y, int finalX, int finalY, int paths)
{
var originalValue = grid[x, y];
if (originalValue == 6)
{
paths++;
return paths;
}
grid[x, y] = 1; // prevent deeper recursion from coming back to this space
if ((grid[x + 1, y] != 1) && (x+1 < finalX))
return recursiveCheck(grid, x + 1, y, finalX, finalY, paths);
if ((grid[x, y+1] != 1) && (y+1 < finalY))
return recursiveCheck(grid, x, y+1, finalX, finalY, paths);
if ((grid[x - 1, y] != 1) && (x > 0))
return recursiveCheck(grid, x - 1, y, finalX, finalY, paths);
if (grid[x, y - 1] != 1 && y >0)
return recursiveCheck(grid, x, y - 1, finalX, finalY, paths);
grid[x, y] = originalValue; // allow other path checking to revisit this space.
return 0;
}
公共静态int递归检查(int[,]网格,int x,int y,int finalX,int finalY,int路径)
{
var原始值=网格[x,y];
如果(原始值==6)
{
路径++;
返回路径;
}
grid[x,y]=1;//防止更深层次的递归返回到此空间
如果((网格[x+1,y]!=1)和&(x+1public List<(int r, int c)> RecursiveCheck(int[,] grid, (int r, int c) initial, int goal)
{
var path = new List<(int r, int c)>(new[] { initial });
return RecursiveCheck(grid, path, goal);
}
private List<(int r, int c)> RecursiveCheck(int[,] grid, List<(int r, int c)> path, int goal)
{
foreach (var neighbour in GetNeighbours(grid, path.Last()))
{
if (!path.Contains(neighbour))
{
var next = path.Concat(new[] { neighbour }).ToList();
if (grid[neighbour.r, neighbour.c] == goal)
{
return next;
}
else if (grid[neighbour.r, neighbour.c] == 0)
{
return RecursiveCheck(grid, next, goal);
}
}
}
return new List<(int r, int c)>();
}
int[,] grid = new int[3, 5]
{
{ 0, 1, 0, 0, 0},
{ 0, 1, 0, 1, 0},
{ 0, 0, 0, 1, 6},
};
List<(int r, int c)> path = RecursiveCheck(grid, (r: 0, c: 0), 6);
Console.WriteLine(path.Count);