[英]Finding valid neighbors in 2D array
所以,我有一個4x4 2D陣列(它總是這些尺寸)。 從數組上的某個位置開始,一些行和列,我想找到所有有效的鄰居。 到目前為止,我有一個非常笨重的實現。
//add row
if ( !((row + 1) > 3)) {
//do stuff
}
//sub row
if ( !((row - 1) < 0)) {
//do stuff
}
//add col
if ( !((col + 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<Integer> getNeighbors(int i, int j, int x, int y, int[][] cellValues) {
ArrayList<Integer> 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<int[]> getNeighbors(x, y, maxX, maxY) {
neighbors = new ArrayList<int[]>;
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會給你一個ArrayIndexOutOfBounds異常,因為記住最后一個索引是4 - 1。
什么構成有效的鄰居?
如果你想要的只是檢索數組邊界內一個單元格的所有鄰居(包括對角線),這就足夠了。
public List<Element> getNeighbors( int x, int y ) {
List<Element> 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 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 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
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.