2013-10-19 48 views
0

所以,我有一個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 

這是殘酷的。當我開始瞭解元素的位置時,我覺得我不需要檢查每個鄰居。有任何想法嗎?

+0

取決於'//做stuff'是什麼。你能把它全部改爲一行嗎? –

+0

如果一個位置是一個有效的鄰居(達到做東西),它只是將行,列位置添加到列表中。或者更具體地說,創建一個Location(行,列)對象,並將其添加到列表中。 – rhl13

+0

Unsolicited =>我會盡量保持你的代碼正面;意思是否定你的'!'。例如,'if(!((col-1)<0))'變成'if((col-1)> = 0)'。 – ChiefTwoPencils

回答

1

這是我怎麼會做這樣一個現實:得到的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 
} 
+0

我喜歡這個想法。雖然對於非常大的矩陣可能不是最高效的。 – Radiodef

+0

爲什麼不呢?無論矩陣多大,它的運行時間是O(1),只要你只需要一個單元的鄰居。 –

+0

是的,我想我只是看它與自己的條件相比,在這種情況下,只有更多的東西。我必須說這是圍繞「//做什麼」做的最可讀的語法。 – Radiodef

1

不幸你告訴計算機該做什麼,計算機除了告訴它之外什麼都不知道。

您可以自動這種非標準的循環邏輯的一個小東西,雖然我猜:

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在第三次迭代。

但需要注意的是,在你的代碼,覈對(東西)> 4會給你產生ArrayIndexOutOfBounds異常,因爲記得上次指數是4 - 1.

0

什麼構成一個有效的鄰居?

如果您只想檢索數組邊界內的單元格的所有鄰居(包括對角線),這就足夠了。

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; 
} 
0

我會這樣做的方式是有一個單獨的方法。

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); 
} 

當然,你不必包括在此方法的額外整數你從打電話,但我做到了額外的代碼的可讀性。

0
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]; 
}} 
3

對於下面代碼(x,y)尺寸的任何2D陣列cellValues[][]可用於得到所有8個鄰居的任何細胞(i,j)。代碼將默認返回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; 
} 
0

這是我的解決方案:

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 
      } 

     } 

    } 

}