在2D数组中查找有效的邻居

所以,我有一个4×4 2Darrays(它总是这些尺寸)。 从数组上的某个位置开始,一些行和列,我想找到它的所有有效邻居。 到目前为止,我有一个非常笨重的实现。

//add row if ( !((row + 1) > 3)) { //do stuff } //sub row if ( !((row - 1)  3)) { //do stuff } //sub col if ( !((col - 1) < 0)) { //do stuff } ... and so on 

这是残酷的。 当我开始知道元素的位置时,我觉得我不需要检查每个邻居。 有任何想法吗?

对于任何2D数组cellValues[][] of (x,y)维度,代码可用于获取任何单元格(i,j)所有8个邻居。 代码默认返回0

 public static ArrayList getNeighbors(int i, int j, int x, int y, int[][] cellValues) { ArrayList neighbors = new ArrayList<>(); if(isCabin(i, j, x, y)) { if(isCabin(i + 1, j, x, y)) neighbors.add(cellValues[i+1][j]); if(isCabin(i - 1, j, x, y)) neighbors.add(cellValues[i-1][j]); if(isCabin(i, j + 1, x, y)) neighbors.add(cellValues[i][j+1]); if(isCabin(i, j - 1, x, y)) neighbors.add(cellValues[i][j-1]); if(isCabin(i - 1, j + 1, x, y)) neighbors.add(cellValues[i-1][j+1]); if(isCabin(i + 1, j - 1, x, y)) neighbors.add(cellValues[i+1][j-1]); if(isCabin(i + 1, j + 1, x, y)) neighbors.add(cellValues[i+1][j+1]); if(isCabin(i - 1, j - 1, x, y)) neighbors.add(cellValues[i-1][j-1]); } return neighbors; } public static boolean isCabin(int i, int j, int x, int y) { boolean flag = false; if (i >= 0 && i <= x && j >= 0 && j <= y) { flag = true; } return flag; } 

以下是我的方法:获取有效邻居的x,y对列表的方法,给定任意[x,y]点并推广到任何数组大小:

 public List getNeighbors(x, y, maxX, maxY) { neighbors = new ArrayList; if x > 0: neighbors.add({x-1, y}); if y > 0: neighbors.add({x, y-1}); if x < maxX: neighbors.add({x+1, y}); if x < maxY: neighbors.add({x, y+1}); return neighbors; } [...] for (int[] coords : getNeighbors(x, y, 4, 4)) { // do stuff } 

不幸的是,通过编写代码,你告诉计算机该做什么,而计算机除了你告诉它之外什么都不知道。

我猜你可以使用非标准循环逻辑自动完成这种事情:

 for (int coff = -1; coff < 3; coff += 2) { for (int roff = -1; roff < 3; roff += 2) { if ( col + coff >= 0 && col + coff < array.length && row + roff >= 0 && row + roff < array[row].length) { // do stuff with array[col + coff][row + roff] } } } 

该循环结构将列和行的偏移从-1翻转为1,然后在第3次迭代时变为3时断开。

但是请注意,在你的代码中,检查!(stuff)> 4会给你一个ArrayIndexOutOfBoundsexception,因为记住最后一个索引是4 - 1。

我这样做的方法是采用一种单独的方法。

 public void example(int changeSign, boolean shouldCheckRow,boolean shouldCheckColumn){ int num = 4; if(changeSign < 0) num = 0; if(shouldCheckRow) //adding a negative is the same as subtracting so if you add -1, you're really subtracting by one. if(!((row + changeSign) < num)) //do stuff else if(!((col + changeSign) < num)) //do stuff } 

方法调用将是

 public static void main(String args[]){ int shouldTestRight = 1; int shouldTestLeft = -1; int shouldTestUp = 1; int shouldTestDown = -1; // so if you want to test up or right, the first parameter should be positive // if you want to test for down or left, the first parameter should be negative // this is because the negative will flip the sign. // if you should change the row, the second parameter should be true // if you should change the column, the third parameter should be true. example(shouldTestRight,true,false); example(shouldTestLeft,true,false); example(shouldTestUp,false,true); example(shouldTestDown,false,true); } 

当然,您不必在要调用的方法中包含额外的int,但我这样做是为了获得额外的代码可读性。

什么构成有效的邻居?

如果你想要的只是检索数组边界内一个单元格的所有邻居(包括对角线),这就足够了。

 public List getNeighbors( int x, int y ) { List neighbors = new ArrayList<>(); for( int i = -1; i <= 1; ++i ) { for( int j = -1; j <= 1; ++j ) { if( i == 0 && j == 0 ) { continue; } if( i + x >= 0 && i + x < array.length && j + y >= 0 && j + y < array[0].length ) { // we found a valid neighbor! neighbors.add( array[i][j] ); } } } return neighbors; } 
 public class FindingNeighboursInMatrix { public static void main(String[] args) { int array[][] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } }; for (int i = 0; i < array.length; i++) { for (int j = 0; j < array[0].length; j++) { System.out.println("neightbours of " + array[i][j]); int neb[] = findneighbours(i, j, array); for (int k = 0; k < neb.length; k++) { if (neb[k] != -1) { System.out.print(" " + neb[k] + ","); } } System.out.println(); } } } public static int[] findneighbours(int i, int j, int matrix[][]) { int neb[] = new int[8]; // top row neb[0] = getvalue(i - 1, j - 1, matrix); neb[1] = getvalue(i - 1, j, matrix); neb[2] = getvalue(i - 1, j + 1, matrix); // left element neb[3] = getvalue(i, j - 1, matrix); // right element neb[4] = getvalue(i, j + 1, matrix); // bottom row neb[5] = getvalue(i + 1, j - 1, matrix); neb[6] = getvalue(i + 1, j, matrix); neb[7] = getvalue(i + 1, j + 1, matrix); return neb; } public static int getvalue(int i, int j, int matrix[][]) { int rowSize = matrix.length; int colSize = matrix[0].length; if (i < 0 || j < 0 || i > rowSize - 1 || j > colSize - 1) { return -1; } return matrix[i][j]; }} 

这是我的解决方案:

 public int[4][4] array2d; //don't forget to fill it! private void adjustNeighbors(int xCoord, int yCoord) { for (int yi = y-1; yi <= yCoord+1; yi++) { //loop through the neighbors for (int xi = x-1; xi <= xCoord+1; xi++) { try { if (!(xCoord != xi && yCoord != yi)) { array2d[y][x]++; //do whatever you want to all the neighbors! } } catch (Exception e) { // something is out of bounds } } } }