Algorithm 使用递归方法查找闭合路径或区域
我有一个二维数组中的对象,我想穿过它们,从上到左,从右,我想检查是否有循环,或者更好的方法,形成闭合区域。请参阅此图片以获得更好的解释 实际上,我有一个X X Y的插槽,当用户触摸任何区域时,它会在那里添加砖块,所以我想做的是,每次用户添加砖块时,检查它是否正在创建一个闭合路径 我已经为此编写了递归函数,但它工作得不好,它总是只针对顶部,而不是右侧和左侧。这是密码Algorithm 使用递归方法查找闭合路径或区域,algorithm,recursion,lua,coronasdk,Algorithm,Recursion,Lua,Coronasdk,我有一个二维数组中的对象,我想穿过它们,从上到左,从右,我想检查是否有循环,或者更好的方法,形成闭合区域。请参阅此图片以获得更好的解释 实际上,我有一个X X Y的插槽,当用户触摸任何区域时,它会在那里添加砖块,所以我想做的是,每次用户添加砖块时,检查它是否正在创建一个闭合路径 我已经为此编写了递归函数,但它工作得不好,它总是只针对顶部,而不是右侧和左侧。这是密码 function checkTrap(y,x) if all_tiles[y][x].state == "changed" th
function checkTrap(y,x)
if all_tiles[y][x].state == "changed" then --if brick is added at that location
last_move_y = y
last_move_x = x
--check for top
y = y - 1
if( y >= 1 and y <= 6 and (last_move_y ~= y or last_move_x ~= x) ) then
print("Moved to top at"..y..", "..x)
return checkTrap(y, x)
end
--check for bottom
y = y + 1
if( y >= 1 and y <= 6 and (last_move_y ~= y or last_move_x ~= x) ) then
print("Moved to bottom at"..y..", "..x)
return checkTrap(y, x)
end
--check for left
x = x - 1
if( x >= 1 and x <= 6 and (last_move_y ~= y or last_move_x ~= x) ) then
print("Moved to left at"..y..", "..x)
return checkTrap(y, x)
end
--check for right
x = x + 1
if( x >= 1 and x <= 6 and (last_move_y ~= y or last_move_x ~= x) ) then
print("Moved to right at"..y..", "..x)
return checkTrap(y, x)
end
elseif all_tiles[y][x] == object then
print("it's a loop"..y..", "..x)
return true;
else
print("not changed")
return false
end
end
功能检查陷阱(y,x)
如果所有的_tile[y][x].state==“已更改”,那么——如果在该位置添加了砖
最后一步
最后一步x=x
--检查顶部
y=y-1
如果(y>=1和y=1和y=1和x=1和x实现的结构不会递归到其他方向,因为只调用了第一个分支;不知何故,应该包括所有的邻居。显然,您试图在数组上实现一种。这种方法似乎绝对正确,但必须将一个单元的所有邻居都考虑在内计数。最有帮助的可能是进行连接组件分析并填充所有接触边界的连接组件。编辑:
相反,如果使用黑色单元格进行搜索,我们应该使用白色单元格进行搜索,因为您的目标是找到由黑色单元格包围的区域,即使是对角相邻的区域。我们应该找到一组仅由黑色单元格包围的白色单元格,而不是整个主网格的边框。这应该满足您的目的
JS小提琴:
这是我提出的修正算法:
for each cell and until closed area not found
if white and visitedValue = -1
push cell to stack
while stack has values and closed area not found
pop cell from stack
if invalid cell // Cell coordinates are invalid
this area is not closed, so break from the while
else
if white
if visitedValue = -1
{
mark visited
push neighboring four cells to the stack
}
else
if visitedValue > currVisitNumber // The current cells are part of previous searched cell group, which was not a closed group.
this area is not closed, so break from the while
if closed area found
show message
使用JQuery编程:
function findArea() {
var currFlag = -1, isvisited = [], isClosed = false;
for (var k = 0; k < rows; k++) { // Initialize the isvisited array
isvisited[k] = [];
for (var m = 0; m < cols; m++)
isvisited[k][m] = -1;
}
for (var k = 0; k < rows && !isClosed; k++)
for (var m = 0; m < cols && !isClosed; m++) {
if (!isblack[k][m] && isvisited[k][m] == -1) { // Unvisited white cell
var cellsi = [k], cellsj = [m];
currFlag++;
isClosed = true;
while (cellsi.length > 0 && isClosed) { // Stack has cells and no closed area is found
var p = cellsi.pop(), q = cellsj.pop();
if (p >= 0 && p < rows && q >= 0 && q < cols) { // The cell coord.s are valid
if (!isblack[p][q])
if (isvisited[p][q] == -1) {
isvisited[p][q] = currFlag; // Mark visited
cellsi.push(p - 1); // Push the coord.s of the four adjacent cells
cellsj.push(q);
cellsi.push(p + 1);
cellsj.push(q);
cellsi.push(p);
cellsj.push(q + 1);
cellsi.push(p);
cellsj.push(q - 1);
}
else
if (isvisited[p][q] < currFlag) // The current group of white cells was part of a previous group of white cells which were found to be unbound by the black cells. So, skip this group.
isClosed = false;
}
else
isClosed = false; // The current cell is out of border. Hence skip the whole group.
}
}
}
if (isClosed)
alert('Closed area found');
}
函数findArea(){
var currFlag=-1,isvisited=[],isClosed=false;
对于(var k=0;k0&&isClosed){//堆栈有单元格,未找到闭合区域
var p=cellsi.pop(),q=cellsj.pop();
如果(p>=0&&p=0&&q
JS Fiddle:您说过实现的结构不是递归的,您能建议对这种方法进行任何更改吗?我对Lua的了解最多不过是肤浅的;返回类型是什么(在非正式意义上)在函数的checkTrap
?checkTrap返回布尔值之后,递归调用不应立即返回其调用的值,但应存储结果,并将所有结果由和或或组合。您好,感谢您的帮助,但代码工作不正常。在类似[1,2,3]、[4,5,6]的场景中,[7,8,9]如果我在位置5处触摸,那么在位置7处这表示这是一个循环。希望你理解我在这里试图传达的内容?嗨,我尝试了你的新算法,但它不起作用。请看我编辑
function findArea() {
var currFlag = -1, isvisited = [], isClosed = false;
for (var k = 0; k < rows; k++) { // Initialize the isvisited array
isvisited[k] = [];
for (var m = 0; m < cols; m++)
isvisited[k][m] = -1;
}
for (var k = 0; k < rows && !isClosed; k++)
for (var m = 0; m < cols && !isClosed; m++) {
if (!isblack[k][m] && isvisited[k][m] == -1) { // Unvisited white cell
var cellsi = [k], cellsj = [m];
currFlag++;
isClosed = true;
while (cellsi.length > 0 && isClosed) { // Stack has cells and no closed area is found
var p = cellsi.pop(), q = cellsj.pop();
if (p >= 0 && p < rows && q >= 0 && q < cols) { // The cell coord.s are valid
if (!isblack[p][q])
if (isvisited[p][q] == -1) {
isvisited[p][q] = currFlag; // Mark visited
cellsi.push(p - 1); // Push the coord.s of the four adjacent cells
cellsj.push(q);
cellsi.push(p + 1);
cellsj.push(q);
cellsi.push(p);
cellsj.push(q + 1);
cellsi.push(p);
cellsj.push(q - 1);
}
else
if (isvisited[p][q] < currFlag) // The current group of white cells was part of a previous group of white cells which were found to be unbound by the black cells. So, skip this group.
isClosed = false;
}
else
isClosed = false; // The current cell is out of border. Hence skip the whole group.
}
}
}
if (isClosed)
alert('Closed area found');
}