2012-01-30 6 views
0

2 차원 배열 클래스를 자바로 둘러 싸서 가장자리를 감싸고 있습니다. 그래서 10x20 배열에서 엔트리 (2, -1)는 (2,19)와 같을 것이고 (4,22)는 (4,2)와 같을 것입니다. 또한 "평평한 배열"로이 구조체에 액세스 할 수 있기를 원하므로 객체를 저장하기 위해 1D 배열과 같은 구조를 사용하게 될 것입니다. 1D 배열을 사용 하겠지만 제네릭 형식을 사용할 수 없으므로 대신 ArrayList를 사용하고 있습니다. 수업은 아직 끝나지 않았지만 아래 코드를 게시했습니다.가장자리 배열로 자바의 2D 배열 클래스

첫 번째 질문은 알고리즘입니다. 아래 코드에서 modRow (i) 및 modCol (j) 함수를 사용하여 요소 (i, j)에 액세스합니다. 그것은 잘 작동하지만 누군가가 이것을하는 더 좋은 방법을 생각할 수 있는지 궁금하네요. 이 함수는 get (i, j) 함수에 의해 호출됩니다. 최대한 빨리 요소에 액세스 할 수 있기를 원합니다.

두 번째 질문은 Java에만 국한된 것입니다. Java에 상당히 익숙하며이 코드를 C++ 프로젝트에서 가져 오는 것입니다. 배열 (ArrayList에 저장 됨)의 위치 i에 요소를 설정할 수있는 set() 함수가 있습니다. 그러나 set 함수는 add() 함수가 이미 호출 된 경우에만 작동하고 평면화 된 배열의 위치 i에 요소를 설정합니다. 누구든지 내가 어떻게이 수업을 더 잘하게 할 수 있는지에 대한 제안이 있다면 나는 그들을 기쁘게 볼 것입니다.

import java.util.*; 

public class Grid<T> { 

    ArrayList<T> array; // holds objects in grid - would rather use an array 
         // but that won't support generics 
    int rows; // number of rows in grid 
    int cols; // number of cols in grid 
    int length; // total number of objects in grid - maybe just get this from ArrayList 
    int conNum; // number of connections for each point on grid (either 4 or 8) 
       // used for determining distances between points on the grid 

    // constructor 
    Grid(int row, int col, int numCon) { 
     rows = row; 
     cols = col; 
     length = rows * cols; 
     conNum = numCon; 
     array = new ArrayList<T>(length); 
    } 

    // returns total size of grid 
    public int len() { 
     return length; 
    } 

    // returns number of rows 
    public int row() { 
     return rows; 
    } 

    // returns number of columns 
    public int col() { 
     return cols; 
    } 

    // wish I didn't have to use this 
    // would be nice to just be able to use set(int i, T t) 
    public void add(T t) { 
     array.add(t); 
    } 

    // sets object i in flattened out array 
    public void set(int i, T t) { 
     array.set(i, t); 
    } 

    // returns object i in flattened out array 
    // for faster access when user just needs to iterate through all objects 
    // in grid without respect to position in 2D grid 
    public T get(int i) { 
     return array.get(i); 
    } 

    // returns the row position of i in grid - adjusted for warp around edges 
    // is there a better way to do this? 
    private int modRow(int i) { 
     if(i >=0) { 
      if(i < rows) { 
       return i; 
      } else { // i >= rows 
       return i % rows; 
      } 
     } else { // i < 0 
      return (i % rows + rows) % rows; 
     } 
    } 

    // returns the column position of j in grid - adjusted for warp around edges 
    // is there a better way to do this? 
    private int modCol(int j) { 
     if(j >=0) { 
      if(j < cols) { 
       return j; 
      } else { // j >= cols 
       return j % cols; 
      } 
     } else { // j < 0 
      return (j % cols + cols) % cols; 
     } 
    } 

    // sets object at (i,j) value from store adjusted for wrap around edges 
    public void set(int i, int j, T t) { 
     array.set(modRow(i) * cols + modCol(j), t); 
    } 

    // gets object at (i,j) value from store adjusted for wrap around edges 
    public T get(int i, int j) { 
     return array.get(modRow(i) * cols + modCol(j)); 
    } 

    // returns distance on the grid between two objects at (y1,x1) and (y2,x2) 
    public int dist(int y1, int x1, int y2, int x2) { 
     int y = distFirst(y1, y2); 
     int x = distSecond(x1, x2); 
     if (conNum == 4) // taxicab distance 
     { 
      return y + x; 
     } else { //if(conNum == 8) supremum distance 
      return Math.max(y, x); 
     } 
    } 

    // returns distance on the grid between the first coordinates y1 & y2 of two objects 
    public int distFirst(int y1, int y2) { 
     int dist = Math.abs(modRow(y2) - modRow(y1)); 
     return Math.min(dist, rows - dist); 
    } 

    // returns distance on the grid between the second coordinates x1 & x2 of two objects 
    public int distSecond(int x1, int x2) { 
     int dist = Math.abs(modCol(x2) - modCol(x1)); 
     return Math.min(dist, cols - dist); 
    } 
} 

답변

0

무엇 때문에 배열을 사용하여 제네릭을 사용할 수 없다고 생각하는지 잘 모릅니다. 따라서 내부 저장소 정의를 변경하고 하트 세트에 대한 호출을 설정하십시오.

modRows/modCols 함수는 (약간) 더 효율적일 수 있습니다. 인덱스는 한 방향으로 만 범위를 벗어나기 때문에 중첩 된 if 체크를 제거 할 수 있습니다.

if(index < 0) return index + max_size; 
else if(index >= max_size) return index % max_size; 
else return index; 
+0

고맙습니다. 인덱스가 0보다 작 으면 인덱스> = -max_size 인 경우에만 작동합니다. 내가 그 아래로 갈 계획이 아니기 때문에 아마 내 사용에는 충분할 것이다. – COM

+0

T [] 배열을 시도한 다음 array = new T [length]를 시도했지만 오류가 발생했습니다. – COM

0

@Perception : 원래 index < 0 수표에 문제가 있습니까?

if(index < 0) return (index % max_size + max_size) % max_size; // <-- like that 
else if(index >= max_size) return index % max_size; 
else return index;