Java 배열 순회/탐색 하기 + 델타 delta
🧑‍💻 𝗣𝗿𝗼𝗴𝗿𝗮𝗺𝗺𝗶𝗻𝗴/Java

Java 배열 순회/탐색 하기 + 델타 delta

 

 

 

 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 델타


 

728x90