修改:已解决,请参阅下面的帖子。
我正在用Java实现棋盘游戏,需要开发一种算法来查找2d阵列中单个单元的“连接”单元数。
编辑:通过连接,我的意思是与我正在开始的单元格具有相同的值。如果方法调用值为x的单元格,我需要找到与它共享边缘的所有那些(不是对角线)。
IE如果我有这个2d的1和0数组,我想找到我选择的单个单元格中最多的连接单元格:
[1][1][1][0]
[1][0][1][1]
[1][0][0][1]
[1][0][0][1]
在[0] [0]上运行算法将返回10,因为有6个1连接在右侧路径上,3个在左侧路径上连接。
有没有一种已知的方法可以解决这个问题?如果没有,你会如何解决它?我绞尽脑汁似乎无法找到方法。任何建议表示赞赏。
答案 0 :(得分:2)
您可能需要查看一些路径查找算法。
最常见也是最快的是Dijkstra's Algorithm
这个概念很容易理解和实施。找到一条路径,你可以找到你正在搜索的区域周围1或0的连接。
在Java中查看使用Dijkstra算法对2D阵列进行路径查找。 Path Finding
通过查看环绕声“节点”(1或0),您可以找到“连接”部分。
答案 1 :(得分:1)
解决了,这就是我所做的:
// Java the board game: find connected spaces
public class findConnectedCells
{
public static int findNumberConnected(int a, int b, int[][] z)
{
boolean canUp = (a - 1 >= 0);
boolean canDown = (a + 1 < z.length);
boolean canRight = (b + 1 < z[0].length);
boolean canLeft = (b - 1 >= 0);
int value = z[a][b];
int up = 0;
int down = 0;
int right = 0;
int left = 0;
z[a][b] = 2;
if (canUp && z[a-1][b] == value)
{
up = findNumberConnected(a-1,b,z);
}
if (canDown && z[a+1][b] == value)
{
down = findNumberConnected(a+1,b,z);
}
if (canLeft && z[a][b-1] == value)
{
left = findNumberConnected(a,b-1,z);
}
if (canRight && z[a][b+1] == value)
{
right = findNumberConnected(a,b+1,z);
}
return up + left + right + down + 1;
}
public static void main(String[] args) {
System.out.println("Finding connections");
int[][] z = new int[][]{
{ 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1 },
};
int x = 0;
int y = 0;
System.out.println("Number of connected cells from "+x+","+y+" is: "+findNumberConnected(x,y,z));
}
}
答案 2 :(得分:0)
检查深度优先搜索。递归算法的想法如下:
创建空的单元格堆。
添加到堆栈起始位置(例如0,0)。
拉出堆叠中的单元格(这意味着 - 将其从堆栈中移除并准备探索它)并探索此单元格具有的相邻单元格,添加符合您条件的所有相邻单元格(== 1并共享边缘)到同一堆栈。 Mark看到拉出细胞。
重复#3,直到你的桌子上看不见的单元格,或者你面对的是一组相邻的单元格,这些单元格没有任何符合你条件的单元格或者堆栈变空。
你应该以某种方式记住你传递的方式并选择最长的一个(包含更多的1)
这是一个非常简单和简短的算法。 祝你好运!
答案 3 :(得分:0)
深度优先搜索是关键算法和更好的解决方法,因为如果数组在每个维度中都是大数字,那么您将得到 StackOverFlow异常。首先,将细胞连接到过去,如下所示;左上,上,右上和左上。这将涵盖所有可能的联系。
_ _ _
_ x
然后,一旦有效连接单元格,只需在所有矩阵中进行深度优先遍历。当您在该区域时,继续增加区域计数,就像您进行深度优先遍历一样,直到您再次找到未访问的节点并执行相同操作。如果新区域计数较大,则将其替换为最大区域计数。
以下是实施
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;
import java.util.stream.Stream;
public class SolutionNoRecursion {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int row = Integer.valueOf(in.nextLine());
Node[][] matrix = new Node[row][Integer.valueOf(in.nextLine())];
int count = 0;
LinkedList<Node> nodes = new LinkedList<>();
while(row-->0){
int[] numbers = Stream.of(in.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
for (int column = 0; column < numbers.length; column++) {
if(numbers[column] == 1){
Node node = new Node();
nodes.add(node);
matrix[count][column] = node;
if(count > 0 && count <= matrix.length){
Node upperNode = matrix[count-1][column];
connectNodesToEachOther(node, upperNode);
if(column < numbers.length-1){
Node upperRightNode = matrix[count-1][column+1];
connectNodesToEachOther(node, upperRightNode);
}
}
if(column > 0){
Node leftNode = matrix[count][column-1];
connectNodesToEachOther(node, leftNode);
}
if(column>0 && count>0){
Node upperLeftNode = matrix[count-1][column-1];
connectNodesToEachOther(node, upperLeftNode);
}
}
}
count++;
}
in.close();
int maxSoFar = 0;
for (Node node : nodes) {
if(node.visited){
continue;
}
node.visited = true;
int regionCount = 1;
Stack<Node> stack = new Stack<>();
stack.push(node);
while(!stack.empty()){
Node connection = stack.pop();
if(!connection.visited){
connection.visited = true;
regionCount++;
}
for(Node nodeCon : connection.connections){
if(!nodeCon.visited){
stack.push(nodeCon);
}
}
}
maxSoFar = regionCount > maxSoFar ? regionCount : maxSoFar;
}
System.out.println(maxSoFar);
}
protected static void connectNodesToEachOther(Node node, Node upperNode) {
if(upperNode != null){
node.connections.add(upperNode);
upperNode.connections.add(node);
}
}
}
class Node{
boolean visited = false;
List<Node> connections = new LinkedList<>();
}