2차원 배열 순회/탐색 하기
순회/탐색 로직
1. X 를 만나면
2. X 가 움직이면서
3. X 주변을 탐색한다.
- 좌우 & 상하
- 4방
- 8방
💡 주의할 점 !
순회를 하는 범위가 배열의 범위를 넘어가서는 안된다.
(즉, 특정 좌표로부터 주변을 탐색하는 경우 배열의 범위를 벗어나지 않도록 해야한다.)
input.txt
2 3 1 4
1 X 3 2
3 4 X X
X 4 1 5
다음과 같은 입력이 들어온다고 합시다.
X 를 기준으로 상하좌우(4방)에 있는 숫자를 출력해보도록 합시다.
좌우 순회/탐색 하기
// 좌우 순회하기
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
if (arr[r][c] == 'X') {
System.out.println("\nX 위치: " + r + " " + c);
if (c - 1 >= 0) System.out.print(arr[r][c - 1] + " ");
if (c + 1 < N) System.out.print(arr[r][c + 1] + " ");
}
}
}
전체 코드
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
public class Test {
static final int N = 4;
public static void main(String[] args) throws FileNotFoundException {
System.setIn(new FileInputStream("src/input.txt"));
Scanner sc = new Scanner(System.in);
// 배열 입력 받기
char[][] arr = new char[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
arr[i][j] = sc.next().charAt(0);
}
}
// 배열 출력 하기
for (int i = 0; i < N; i++) {
System.out.println(Arrays.toString(arr[i]));
}
// 좌우 순회하기
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
if (arr[r][c] == 'X') {
System.out.println("\nX 위치: " + r + " " + c);
if (c - 1 >= 0) System.out.print(arr[r][c - 1] + " ");
if (c + 1 < N) System.out.print(arr[r][c + 1] + " ");
}
}
}
}
}
좌우는 컬럼만 한 칸씩 움직이면 된다.
단 배열 범위가 좌를 탐색할 때, 0보다 커야하고 우를 탐색할 때, N 보다 작아야 한다.
4방 순회/탐색 하기
// 4방 순회하기
// 1. 상 [r-1][c]
// 2. 하 [r+1][c]
// 3. 좌 [r][c-1]
// 4. 우 [r][c+1]
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
if (arr[r][c] == 'X') {
System.out.println("\nX 위치: " + r + " " + c);
if (r - 1 >= 0) System.out.print(arr[r - 1][c] + " ");
if (r + 1 < N) System.out.print(arr[r + 1][c] + " ");
if (c - 1 >= 0) System.out.print(arr[r][c - 1] + " ");
if (c + 1 < N) System.out.print(arr[r][c + 1] + " ");
}
}
}
전체 코드
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
public class Test {
static final int N = 4;
public static void main(String[] args) throws FileNotFoundException {
System.setIn(new FileInputStream("src/input.txt"));
Scanner sc = new Scanner(System.in);
// 배열 입력 받기
char[][] arr = new char[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
arr[i][j] = sc.next().charAt(0);
}
}
// 배열 출력 하기
for (int i = 0; i < N; i++) {
System.out.println(Arrays.toString(arr[i]));
}
// 4방 순회하기
// 1. 상 [r-1][c]
// 2. 하 [r+1][c]
// 3. 좌 [r][c-1]
// 4. 우 [r][c+1]
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
if (arr[r][c] == 'X') {
System.out.println("\nX 위치: " + r + " " + c);
if (r - 1 >= 0) System.out.print(arr[r - 1][c] + " ");
if (r + 1 < N) System.out.print(arr[r + 1][c] + " ");
if (c - 1 >= 0) System.out.print(arr[r][c - 1] + " ");
if (c + 1 < N) System.out.print(arr[r][c + 1] + " ");
}
}
}
}
}
4방을 탐색할 때는, 상하좌우를 합치면 된다.
단 상이나 좌 같은 경우는 배열 범위가 0보다 커야하고, 하나 우 같은 경우는 배열 범위가 N 보다 작아야 한다.
8방 순회/탐색 하기
// 8방 순회하기
// 1. 상 [r-1][c] 2. 하 [r+1][c]
// 3. 좌 [r][c-1] 4. 우 [r][c+1]
// 5. 좌상 [r-1][c-1] 6. 우상 [r-1][c+1]
// 7. 좌하 [r+1][c-1] 8. 우하 [r+1][c+1]
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
if (arr[r][c] == 'X') {
System.out.println("\nX 위치: " + r + " " + c);
// 상하좌
if (r - 1 >= 0) System.out.print(arr[r - 1][c] + " ");
if (r + 1 < N) System.out.print(arr[r + 1][c] + " ");
if (c - 1 >= 0) System.out.print(arr[r][c - 1] + " ");
if (c + 1 < N) System.out.print(arr[r][c + 1] + " ");
System.out.println();
// 대각선 4방
if (r - 1 >= 0 && c - 1 >= 0) System.out.print(arr[r - 1][c - 1] + " ");
if (r - 1 >= 0 && c + 1 < N) System.out.print(arr[r - 1][c + 1] + " ");
if (r + 1 < N && c - 1 >= 0) System.out.print(arr[r + 1][c - 1] + " ");
if (r + 1 < N && c + 1 < N) System.out.print(arr[r + 1][c + 1] + " ");
}
}
}
전체 코드
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
public class Test {
static final int N = 4;
public static void main(String[] args) throws FileNotFoundException {
System.setIn(new FileInputStream("src/input.txt"));
Scanner sc = new Scanner(System.in);
// 배열 입력 받기
char[][] arr = new char[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
arr[i][j] = sc.next().charAt(0);
}
}
// 배열 출력 하기
for (int i = 0; i < N; i++) {
System.out.println(Arrays.toString(arr[i]));
}
// 8방 순회하기
// 1. 상 [r-1][c] 2. 하 [r+1][c]
// 3. 좌 [r][c-1] 4. 우 [r][c+1]
// 5. 좌상 [r-1][c-1] 6. 우상 [r-1][c+1]
// 7. 좌하 [r+1][c-1] 8. 우하 [r+1][c+1]
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
if (arr[r][c] == 'X') {
System.out.println("\nX 위치: " + r + " " + c);
// 상하좌
if (r - 1 >= 0) System.out.print(arr[r - 1][c] + " ");
if (r + 1 < N) System.out.print(arr[r + 1][c] + " ");
if (c - 1 >= 0) System.out.print(arr[r][c - 1] + " ");
if (c + 1 < N) System.out.print(arr[r][c + 1] + " ");
System.out.println();
// 대각선 4방
if (r - 1 >= 0 && c - 1 >= 0) System.out.print(arr[r - 1][c - 1] + " ");
if (r - 1 >= 0 && c + 1 < N) System.out.print(arr[r - 1][c + 1] + " ");
if (r + 1 < N && c - 1 >= 0) System.out.print(arr[r + 1][c - 1] + " ");
if (r + 1 < N && c + 1 < N) System.out.print(arr[r + 1][c + 1] + " ");
}
}
}
}
}
8방을 구할 때는 대각선 부분을 구해야한다.
이는 상하좌우가 합쳐진 모양과도 같다.
4방 탐색하면서 이미 사용된 숫자는 사용하지 않기
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
public class Test {
static final int N = 4;
public static void main(String[] args) throws FileNotFoundException {
System.setIn(new FileInputStream("src/input.txt"));
Scanner sc = new Scanner(System.in);
// 배열 입력 받기
char[][] arr = new char[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
arr[i][j] = sc.next().charAt(0);
}
}
// 배열 출력 하기
for (int i = 0; i < N; i++) {
System.out.println(Arrays.toString(arr[i]));
}
// 4방 순회하면서 사용한 숫자는 중복 사용하지 않기
int sum = 0;
boolean[] used = new boolean[10];
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
if (arr[r][c] == 'X') {
System.out.println("\nX 위치: " + r + " " + c);
// 상
if (r - 1 >= 0 && arr[r - 1][c] != 'X' && !used[arr[r - 1][c] - '0']) {
System.out.print(arr[r - 1][c] + " ");
sum += arr[r - 1][c] - '0';
used[arr[r - 1][c] - '0'] = true;
}
// 하
if (r + 1 < N && arr[r + 1][c] != 'X' && !used[arr[r + 1][c] - '0']) {
System.out.print(arr[r + 1][c] + " ");
sum += arr[r + 1][c] - '0';
used[arr[r + 1][c] - '0'] = true;
}
// 좌
if (c - 1 >= 0 && arr[r][c - 1] != 'X' && !used[arr[r][c - 1] - '0']) {
System.out.print(arr[r][c - 1] + " ");
sum += arr[r][c - 1] - '0';
used[arr[r][c - 1] - '0'] = true;
}
// 우
if (c + 1 < N && arr[r][c + 1] != 'X' && !used[arr[r][c + 1] - '0']) {
System.out.print(arr[r][c + 1] + " ");
sum += arr[r][c + 1] - '0';
used[arr[r][c + 1] - '0'] = true;
}
}
}
}
System.out.println("\nSUM:" + sum);
sc.close();
}
}
// 상
if (r - 1 >= 0 && arr[r - 1][c] != 'X' && !used[arr[r - 1][c] - '0']) {
System.out.print(arr[r - 1][c] + " ");
sum += arr[r - 1][c] - '0';
used[arr[r - 1][c] - '0'] = true;
}
위를 탐색하는 코드만 뜯어보자면, r - 1 이 0 보다 커야하며 해당 탐색 숫자는 'X'가 아니어야 한다.
왜냐하면 더할려면 숫자여야 하기 때문이다.
또한, used 에서 false 여야 한다. true 면 이미 사용한 숫자 인 것이다.
여기서 중요한 것이, 조건문의 순서가 arr[r-1][c] != 'X' 가 !used[arr[r-1][c] - '0'] 보다 먼저 와야한다.
왜냐하면 후자가 먼저와서 만약 arr[r-1][c]가 X라면 아스키코드로 변경되어 used 배열 범위를 넘어버린다.
따라서 전자가 먼저와서 'X' 문자가 아니라 숫자인지 먼저 확인하고 다음 조건으로 넘어가야 한다.
델타 사용하기
public class Test {
static int[] dy = { -1, 1, 0, 0 };
static int[] dx = { 0, 0, -1, 1 };
public static void main(String[] args) {
int N = 4;
int[][] map = { { 1, 2, 3, 4 },
{ 5, -1, 7, 8 },
{ 9, 10, 11, 12 },
{ 13, 14, -1, 16 } };
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
// 만약 target이 -1 이라면 4방 탐색을 한다.
if (map[y][x] == -1) {
System.out.printf("y:%d x:%d\n", y, x);
for (int d = 0; d < 4; d++) {
int ny = y + dy[d];
int nx = x + dx[d];
if (ny < 0 || ny >= N || nx < 0 || nx >= N) continue;
System.out.print(map[ny][nx] + " ");
}
System.out.println();
}
}
}
}
}
2차원 배열을 두개의 반복문으로 돌면서, 타겟값의 조건을 찾습니다.
그리고 하나의 반복문을 더 돕니다.
이 반복문은 4방을 탐색하는 반복문으로 횟수는 4번 돕니다.
델타 값만큼 돌면서, 유효하지 않은 범위는 continue; 를 합니다. 그래야지 오류가 뜨지 않습니다.
# java 2차원 배열 탐색 # java 2차원 배열 순회 # java 4방 # java 8방 # java 상하좌우 # java 델타
'🧑💻 𝗣𝗿𝗼𝗴𝗿𝗮𝗺𝗺𝗶𝗻𝗴 > Java' 카테고리의 다른 글
Java 4.15 이클립스 설치, 3.9.14 STS 설치 with MAC (0) | 2022.07.17 |
---|---|
Java 설치된 자바 리스트 한번에 보기 with MAC (0) | 2022.07.17 |
Java 배열 min, max 값 찾기 (0) | 2022.07.16 |
Java System.arraycopy() 사용해서 복사하기 (0) | 2022.07.16 |
Java 라이브러리, jar 파일 추가하기 (0) | 2022.07.16 |