🔷 2차 배열의 한 좌표에서 4방향의 인접 배열 요소를 탐색하는 방법
2차 배열의 한 좌표가 바로
델타
💡 0 자리의 인덱스를 그냥 채워버리고 1부터 시작해도 좋다!
배열 인덱스 벗어남 문제도 해결할 수 있고 1부터 시작하면 직관성이 올라갈 수 있다.
💡 델타 행 - dr, 델타 열 - dc로 변수 선언을 해두는 것이 직관적이다.
💡 델타가 맵을 벗어나는지 조건을 통해 확인하며 탐색한다.
public class Main {
static int [][] arr = {{1,2,3}, {4,5,6}, {7,8,9}};
static int N = arr.length;
public static void main(String[] args) {
// 현재 나의 좌표
int r = 3;
int c = 1;
// 상하좌우: 문제에서 주어진 방향이 있으면 그것을 따른다
int [] dr = {-1,1,0,0};
int [] dc = {0,0,-1,1};
// 상하좌우를 2차원 배열로 작성할 수도 있다.
int [][] drc = {{-1,0},{1,0},{0,-1},{0,1}};
for(int d = 0; d < 4; d++) {
int nr = r + dr[d]; // d 방향으로 이동한 곳의 값
int nc = c + dc[d];
int nr2 = r + drc[d][0];
int nc2 = c + drc[d][1];
// 현재 위치가 외곽이거나 모서리일 경우 문제가 발생할 수도 있다.
System.out.println(arr[nr][nc]);
// 그래서 현재 위치가 경계인지 아닌지를 체크해야한다.
// 1. 경계가 아니면 로직 실행
if(isRange2(nr ,nc)) {
System.out.println(arr[nr][nc]);
}
// 2. 경계에 걸친 좌표면 로직 스킵
if(!isRange(nr, nc)) {
continue;
}
System.out.println(arr[nr][nc]);
// 다음 좌표의 값을 비교하고 범위 체크 (위험)
// 범위 체크하고 다음 좌표의 값을 비교 (안전)
} // 4방향 탐색을 위한 반복문
}
public static boolean isRange(int nr ,int nc) {
return !(nr < 0 || nr >= N || nc < 0 || nc >= N);
}
public static boolean isRange2(int nr ,int nc) {
return nr >= 0 && nr < N && nc >=0 && nc<N;
}
}
🔷 임의의 행렬 A가 주어졌을 때 그 행렬 A에서 행과 열을 바꾼 행렬을 행렬 A의 전치행렬이라 한다.
import java.util.Arrays;
public class Main {
static int [][] arr = {{1,2,3}, {4,5,6}, {7,8,9}};
static int N = arr.length;
public static void main(String[] args) {
// 전치 행렬?
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
int tmp = arr[i][j];
arr[i][j] = arr[j][i];
arr[j][i] = tmp;
}
} // 모든 요소를 돌면서 바꾼 것을 한번 더 바꿔버리기 때문에 원래대로 돌아온다.
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
if(i < j) {
int tmp = arr[i][j];
arr[i][j] = arr[j][i];
arr[j][i] = tmp;
}
}
} // 안에 조건을 추가해 절반만 돈다.
for(int i = 0; i < N; i++) {
for(int j = i + 1; j < N; j++) {
if(i < j) {
int tmp = arr[i][j];
arr[i][j] = arr[j][i];
arr[j][i] = tmp;
}
}
} // 초기식을 조작해 이런 식으로 바꿀 수도 있다.
for(int [] a : arr) {
System.out.println(Arrays.toString(a));
}
}
}