2013-03-18 18 views
5

Przepisuję trałowie dla praktyki i napisałem ten fragment kodu, aby uniknąć błędów IndexOutOfBounds. Czy istnieje sposób na uniknięcie tego, więc nie muszę jednoznacznie wypisywać instrukcji if, co jest możliwym błędem? Pomyślałem o zwiększeniu każdego z indeksów w tablicy 2 i po prostu zignorowaniu pierwszego i ostatniego indeksu. Czy brakuje mi czegoś oczywistego?Czy istnieje sposób na uniknięcie tego bloku kodu?

 if (row > 0 && col > 0) 
      ray[row - 1][col - 1] += 1; 
     if (row > 0) 
      ray[row - 1][col] += 1; 
     if (row > 0 && col < height - 1) 
      ray[row - 1][col + 1] += 1; 
     if (col > 0) 
      ray[row][col - 1] += 1; 
     if (col < height - 1) 
      ray[row][col + 1] += 1; 
     if (row < width - 1 && col > 0) 
      ray[row + 1][col - 1] += 1; 
     if (row < width - 1) 
      ray[row + 1][col] += 1; 
     if (row < width - 1 && col < height - 1) 
      ray[row + 1][col + 1] += 1; 

Odpowiedz

5

Zamiast tego można użyć pętli i zdefiniować granice jeden raz. Coś jak:

int startRow = max(row - 1, 0); 
int endRow = min(row + 1, width - 1); 

int startCol = max(col - 1, 0); 
int endCol = min(col + 1, height - 1); 

for (int r = startRow; r <= endRow; r++) 
    for (int c = startCol; c <= endCol; c++) 
     if (r != row || c != col) //it looks like you want to skip this cell 
      ray[r][c] += 1; 

Alternatywnie, jeśli operacja jest odwracalna (jak w tym kodzie, jesteś dodanie 1), można po prostu odwrócić działanie na środku celi po pętli. To byłoby bardziej efektywne, ponieważ eliminuje (co najwyżej) 12 porównań, pod warunkiem, że sama operacja była prosta:

int startRow = max(row - 1, 0); 
int endRow = min(row + 1, width - 1); 

int startCol = max(col - 1, 0); 
int endCol = min(col + 1, height - 1); 

for (int r = startRow; r <= endRow; r++) 
    for (int c = startCol; c <= endCol; c++) 
     ray[r][c] += 1; 

//reverse the operation for the middle cell 
ray[row][col] -= 1; 
+0

Coś wydaje się trochę nie tak. Dlaczego chcesz zacząć od 2, jeśli 'row = 3'? – Makoto

+0

fajne. również użycie min/max będzie bardziej przejrzyste 'startRow = max (0, wiersz-1)' – ZhongYu

+0

@Makoto Kod w pytaniu obchodzi wszystkich sąsiadów 'ray [row] [col]. Więc jeśli 'row = 3', chcemy sprawdzić wszystkie komórki od wiersza 2 do wiersza 4, jeśli istnieją. –

2

można uprościć kod trochę za pomocą zagnieżdżonych if oświadczenia. (Na przykład, nie będzie musiał sprawdzić, czy więcej row > 0 niż raz.)

jednak pójdę z podejmowania tablicę 2 większe n każdy wymiar, niech row różnią się od 1 przez height i col różnią się od 1 przez width i zignoruj ​​to, co dzieje się na krawędziach.

W kodzie, to wydaje się być powiązanie row z width i col z height, co wydaje mi się wstecz.

+0

dobrze, rząd i szerokość są zarówno poziomo, a pozostałe dwa są pionowe. Czułem się bardziej naturalny. Nie myślę jednak o zgrupowaniu rzędu> 0. Dzięki! – elodin

+0

@elodin - Rozumiem, twoja uwaga. Jednak myślę o zmiennej 'row' jako o indeksowaniu wiersza; a ponieważ wiersze są ułożone jeden na drugim, 'wysokość' określa po prostu liczbę wierszy. –

0

Tak można to zrobić z pętli

for(int r=row-1; r<=row+1; r++) 
for(int c=col-1; c<=col+1; c++) 
    if(r>=0 && r<ROWS && c>=0 && c<COLS && !(r==row && c==col)) 
     ray[r][c]++; 
Powiązane problemy