2016-04-21 14 views
2

相鄰數字如何計算一個3x3矩陣,這可能看起來像這樣入住矩陣

1 1 1 
1 0 0 
0 0 0 

和我期望的輸出是所有周邊的人(方括號內爲索引[X,Y] ,我只關心數字,索引是準確的) [0,0] - 2,[1,0] - 3,[2,0] - 1,[0,1] -2等...我不計算中間數字。

我有一個大矩陣,任務是循環遍歷每個數字,想象這個矩陣並計算中間數字周圍有多少個矩陣。 這是我的代碼,但我不能讓它工作。

這裏是我的方法:

public int CheckArea(int cordX, int cordY) 
    { 
     int count = 0; 
     for (int i = cordX - 1; i <= cordX + 1; i++) 
     { 
      for (int j = cordY - 1; j <= cordY + 1; j++) 
      { 
       if (j != cordY && i != cordX && tileField[i, j]) 
       { 
        count++; 
       } 
      } 
     } 
     return count;  
    } 

它不應該是一個索引的問題因爲我設置的矩陣是這樣的:

 tileField = new Boolean[width, height]; 
     for (int x = 0; x < width; x++) 
     { 
      for (int y = 0; y < height; y++) 
      { 
       tileField[x, y] = false; 
      } 
     } 

,但我不打印的第一和最後的行和列等等我的打印方法是:

public void Print() 
    { 
     for (int x = 1; x < this.width-1 ; x++) 
     { 
      for (int y = 1; y < this.height -1; y++) 
      { 
       if (!tileField[x, y]) 
       { 
        Console.Write("0 "); 
       } 
       else 
       { 
        Console.Write("1 "); 
       } 
      } 
      Console.WriteLine(""); 
     } 

    } 
+0

只需找到許多掃雷實施中的一個...... –

+0

你在哪裏調用方法CheckArea? – jdweng

+0

你需要比「我無法工作」更具體。什麼不行?看起來會的。如果你正在檢查你的邊緣,那麼你將在你的數組中搜索第一行和最後一行或第一列和最後一列中的項目。這些項目是什麼? – Marc

回答

2

雖然它可能看起來像這樣使用循環來減少代碼,但你會由於只有8種可能性,因此只需手動檢查每個鄰居。下面的解決方案假設你對圍繞網格進行「包裝」並不感興趣,並且除了要檢查的座標之外,沒有任何其他行/列在該字段中(例如頂部和左側的緩衝區行和列邊緣)。我建議做如下:

public int CheckArea(int cordX, int cordY) 
{ 
    int count = 0; 
    int fieldWidth = tileField.GetLength(1); 
    int fieldHeight = tileField.GetLength(0); 

    // Check for the neighbor to the North 
    if(cordY != 0) 
    { 
     count += GetValueAtCoordinate(cordX,cordY - 1); 
    } 
    // Check for the neighbor to the East 
    if (cordX < fieldWidth - 1) 
    { 
     count += GetValueAtCoordinate(cordX + 1, cordY); 

     // NE neighbor 
     if(cordY != 0) 
     { 
      count += GetValueAtCoordinate(cordX - 1, cordY - 1); 
     } 

     // SE neighbor 
     if(cordY != fieldWidth - 1) 
     { 
      count += GetValueAtCoordinate(cordX - 1, cordY + 1); 
     } 
    } 
    // Check for the neighbor to the South 
    if (cordY < fieldHeight - 1) 
    { 
     count += GetValueAtCoordinate(cordX, cordY + 1); 
    } 
    // Check for the neighbor to the West 
    if (cordX != 0) 
    { 
     count += GetValueAtCoordinate(cordX - 1, cordY); 

     // NW neighbor 
     if(cordY != 0) 
     { 
      count += GetValueAtCoordinate(cordX - 1, cordY - 1); 
     } 

     // SW neighbor 
     if(cordY != fieldHeight - 1) 
     { 
      count += GetValueAtCoordinate(cordX - 1, cordY + 1); 
     } 
    } 

    return count; 
} 

public int GetValueAtCoordinate(int x, int y) 
{ 
    return tileField[x,y] == true ? 1 : 0; 
} 

你可以使用各種其他方法,但是除非你不想使用檢查每個鄰居,我不認爲你的簡單路徑的具體原因真正節省任何時間與循環。我還添加了一個方法,該方法將給定座標上的bool值轉換爲1爲真的值,0爲false,因爲它看起來您的矩陣類型爲bools。

編輯 如果正在處理該作爲1索引陣列,簡單地改變使用該fieldWidth和fieldHeight變量不是邊緣檢查由1

+0

我的第一個想法是做類似的事情,但後來我決定去循環,而不是猜測我有一個非常糟糕的判斷。非常感謝,我會試試這個。 – Crash

+1

沒有一個真正的「正確」的方式來做到這一點。如果這比查看八個鄰居更復雜,那麼可能值得嘗試找到像Roberto下面這樣更簡潔的解決方案。 – exceptionthrown

1
//dx and dy contains a vector of all possible moves: E, NE, N, NW, W, SW, S, SE. 
static int [] dx = {1, 1, 0,-1,-1,-1, 0, 1}; 
static int [] dy = {0, 1, 1, 1, 0,-1, -1, -1}; 


public int CheckArea(int cordX, int cordY) //i assumed that cordX and cordY was a row and a column of the matrix 
{ 

    int count = 0; 
    for(int k = 0; k < dx.length; k++){ 
     int i = dx[k] + cordX; 
     int j = dy[k] + cordY; 
     if(canCount(i,j, matrix) && matrix[i][j] == 1){ 
      count++; 
     } 
    } 



    return count;  
} 
//To check that you are within the bounds of the matrix 
public boolean canCount(int i, int j, int [][] matrix){ 
    return i >= 0 && i < matrix.length && j >= 0 && j < matrix[0].length; 
} 
+0

謝謝你,感謝你的回答,但我會堅持與異常的一個。仍然感謝你的另一種可能的解決方案 – Crash

0

以下方法降低返回一個2D數組代表其中的數字。
請注意,在此數組中null表示元素表示當前元素不是一個元素。

private int?[,] matrixOnesCount(int[,] matrixInput) 
{ 
    int?[,] matrixOutput = new int?[matrixInput.GetLength(0), matrixInput.GetLength(1)]; 

    int rMax = matrixInput.GetLength(0); 
    int cMax = matrixInput.GetLength(1); 

    for (int r = 0; r < rMax; r++) 
     for (int c = 0; c < cMax; c++) 
     { 
      if (matrixInput[r, c] != 1) 
      { 
       matrixOutput[r, c] = null; 
      } 
      else 
      { 
       int numOfOneInNeighbors = 0; 

       numOfOneInNeighbors += (r - 1 >= 0) ? matrixInput[r - 1, c] : 0;      // Top neighborhood 
       numOfOneInNeighbors += (r - 1 >= 0 && c - 1 >= 0) ? matrixInput[r - 1, c - 1] : 0;  // Top-Left neighborhood 
       numOfOneInNeighbors += (c - 1 >= 0) ? matrixInput[r, c - 1] : 0;      // Left neighborhood 
       numOfOneInNeighbors += (r + 1 < rMax && c - 1 >= 0) ? matrixInput[r + 1, c - 1] : 0; // Buttom-Left neighborhood 
       numOfOneInNeighbors += (r + 1 < rMax) ? matrixInput[r + 1, c] : 0;      // Buttom neighborhood 
       numOfOneInNeighbors += (r + 1 < rMax && c + 1 < cMax) ? matrixInput[r + 1, c + 1] : 0; // Buttom-Right neighborhood 
       numOfOneInNeighbors += (c + 1 < cMax) ? matrixInput[r, c + 1] : 0;      // Right neighborhood 
       numOfOneInNeighbors += (r - 1 >= 0 && c + 1 < cMax) ? matrixInput[r - 1, c + 1] : 0;  // Top-Right neighborhood 

       matrixOutput[r, c] = numOfOneInNeighbors; 
      } 
     } 

    return matrixOutput; 
} 


int[,] matrixInput = { { 1, 0, 1 }, 
         { 1, 0, 1 }, 
         { 1, 1, 0 }, 
         { 0, 1, 0 } }; 

int?[,] matrixOutput = matrixOnesCount(matrixInput); 


結果(matrixOutput)是:

1 , null, 1 
3 , null, 2 
3 , 4 , null 
null, 2 , null 
0

或者你可以只檢查i和j下降CheckArea矩陣內是這樣的:

public int CheckArea(int cordX, int cordY) 
{ 
    int count = 0, matrixLenght = 3;//works for any matrix as long as you change the lenght 
    for (int i = cordX - 1; i <= cordX + 1; i++) 
    { 
     for (int j = cordY - 1; j <= cordY + 1; j++) 
     { 
      (i >= 0 && i < matrixLenght && j >= 0 && j < matrixLenght && (i != x || j != y)) 
      { 
       count++; 
      } 
     } 
    } 
    return count;  
}