【发布时间】:2020-10-24 23:01:27
【问题描述】:
对于一个项目,我在程序上生成了一系列坐标为 (0,0) --> (x, y) 的“图块”,其中 (x,y) 是图块数组的最大宽度和高度。然后这个瓦片阵列随机填充正方形,并给出一个入口和多个出口点。我正在尝试创建一个算法,给定一个起点,检查是否可以到达所有出口点。为此,每个图块都包含有关其 NESW 相邻图块的数据,并调用一个递归函数来检查当前图块是否有出口,然后移动到北图块,然后对东、西、南执行相同操作。
这是代码的(伪)示例,除了检查退出之外,它访问所有可用的图块并计算它们(或它的意图):
public class Algo
{
public int Count(Tile tile)
{
tile.Visited = true;
foreach (direction in NESW)
{
if(!tile.direction.IsPopulated & !tile.direction.Visited)
{
return Count(tile.direction) + 1;
}
}
return 0;
}
}
IsPopulated 是一个布尔值,如果图块填充有正方形,则返回 true;Visted 是布尔值,如果图块已被访问,则返回 true。瓦片空间周围有一个正方形的周边,确保算法保持在瓦片空间的范围内
对于这样的平铺布局:
算法返回 17 而不是预期的 21。
似乎,当算法到达无法向任何方向移动的图块时,函数返回计数,而不是返回调用堆栈并再次尝试。
我尝试过的另一个版本按预期工作,但是它没有成效,并且在方法之外改变了类的成员变量。
public class Algo2
{
count = 0;
public void Count(Tile tile)
{
tile.Visited = true;
count += 1;
foreach (direction in NESW)
{
if(!tile.direction.IsPopulated & !tile.direction.Visited)
{
return Count(tile.direction);
}
}
}
}
这将返回值 21 并按预期工作。
为什么有副作用的非结果递归函数可以工作,而没有副作用的有结果函数却不行?
【问题讨论】:
-
那只是返回1,访问顺序和之前一样——按照图片上的顺序访问17个tile
-
是的,抱歉,只需将返回 0 更改为返回 1,因为在第一种方法中,您不计算“叶子”
-
这只是返回一个额外的 1 - 所以 18。我认为问题在于 for 循环中发生的递归,而不是递归是如何停止的。
-
您能提供一些我们可以尝试测试的数据吗?我仍然认为 return 1 应该与您的第二种方法等效
-
您想要什么样的数据? return 0 仅用于结束函数。更改该值会以任意数量添加到返回值,而没有附加逻辑来说明这样做的原因