th42500의 TIL

[Java] 2018 KAKAO BLIND RECRUITMENT - [1차] 비밀지도 (feat. StringIndexOutOfBoundsException) (Lv 1) 본문

Algorithm/Programmers

[Java] 2018 KAKAO BLIND RECRUITMENT - [1차] 비밀지도 (feat. StringIndexOutOfBoundsException) (Lv 1)

th42500 2022. 11. 11. 09:49

https://school.programmers.co.kr/learn/courses/30/lessons/17681

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

✔ 입출력 예제

[1차] 비밀지도 입출력 예제

 

 

💡 포인트

1️⃣ 지도1 또는 지도2 중 어느 하나라도 벽인 부분 = 전체 지도 벽

2️⃣ 지도 1과 지도 2에서 모두 공백인 부분 = 전체 지도 공백

3️⃣ 암호화된 배열을 부호화했을 때 얻어지는 값은 이진수에 해당하는 값의 배열

4️⃣ 모든 지도의 한 변의 길이는 n

      👉 아래와 같이 이진수로 변환했을 때 문자열의 길이가 n보다 짧다면 n자리만큼 왼쪽에 0을 채운 형태여야 함

5️⃣ 결과는 1차원 문자열 배열로 반환

예시 그림 설명

 

 

📌 구현하기

1️⃣ 첫 번째 시도

❓ 풀이과정

1️⃣ Integer.toBinaryString()을 이용하여 arr1과 arr2의 각 수를 2진수 문자열로 바꾸기

2️⃣ 반복문 2개를 이용하여 arr1과 arr2의 각 행의 문자열을 한글자씩 순회하기

3️⃣ 두 배열 중 1개라도 1이라면 map에 #표시

4️⃣ 두 배열 모두 0이라면 map에 공백 표시

5️⃣ 각 행의 문자들을 문자열로 합치는 makeStringArr()을 통해 1차원 String 배열로 합치기

 

✔ 소스코드

import java.util.Arrays;

public class Solution {  // 비밀지도
     private String[] solution(int n, int[] arr1, int[] arr2) {
        char[][] map = new char[n][n];

        // 1.
        for (int i = 0; i < n; i++) {
            String binary1 = Integer.toBinaryString(arr1[i]);
            String binary2 = Integer.toBinaryString(arr2[i]);

            // 2. 
            for (int j = 0; j < n; j++) {
                // 3. 
                if(binary1.charAt(j) == '1' || binary2.charAt(j) == '1') {
                    map[i][j] = '#';
                } else {  // 4.
                    map[i][j] = ' ';
                }
            }
        }
        
        5. 
        String[] resultMap = makeStringArr(map);

        return resultMap;
    }

    private String[] makeStringArr(char[][] map) {
        String[] resultMap = new String[map.length];
        for (int i = 0; i < map.length; i++) {
            StringBuilder sb = new StringBuilder();
            for (int j = 0; j < map[i].length; j++) {
                sb.append(map[i][j]);
            }
            resultMap[i] = sb.toString();
        }
        return resultMap;
    }


    private void printArr(char[][] resultMap) {
        for (int i = 0; i < resultMap.length; i++) {
            System.out.println(Arrays.toString(resultMap[i]));
        }
    }

    public static void main(String[] args) {
        Solution main = new Solution();
        int n = 5;
        int[] arr1 = {9, 20, 28, 18, 11};
        int[] arr2 = {30, 1, 21, 17, 28};

        char[][] resultMap = main.solution(n, arr1, arr2);
        main.printArr(resultMap);
    }

}

 

❗ 실행 결과 

👉 StringIndexOutOfBoundsException 발생

이진수로 변환한 결과 문자열이 지도의 길이 n보다 짧기 때문에 StringIndexOfBoundsException이 발생함

 

 

1️⃣ [Fix] 에러 해결

❓ 풀이과정

위의 풀이과정 1️⃣ 번을 통해 나온 문자열을 n과의 차이만큼 앞에 0을 붙여주는 addZero()라는 메서드를 구현하여 해결

 

✔ 소스코드

import java.util.Arrays;

public class Solution {  // 비밀지도
    private String[] solution(int n, int[] arr1, int[] arr2) {
        char[][] map = new char[n][n];

        // 1. 
        for (int i = 0; i < n; i++) {
            String binary1 = addZero(n, Integer.toBinaryString(arr1[i]));
            String binary2 = addZero(n, Integer.toBinaryString(arr2[i]));

            // 2. 
            for (int j = 0; j < n; j++) {
                // 3. 
                if(binary1.charAt(j) == '1' || binary2.charAt(j) == '1') {
                    map[i][j] = '#';
                } else {  // 4. 
                    map[i][j] = ' ';
                }
            }
        }

        String[] resultMap = makeStringArr(map);

        return resultMap;
    }

    private String addZero(int n, String binary) {
        if(binary.length() < n) {
            String zero = "";
            for (int i = 0; i < n - binary.length(); i++) {
                zero += "0";
            }
            binary = zero + binary;
        }
        return binary;
    }

	5. 
    private String[] makeStringArr(char[][] map) {
        String[] resultMap = new String[map.length];
        for (int i = 0; i < map.length; i++) {
            StringBuilder sb = new StringBuilder();
            for (int j = 0; j < map[i].length; j++) {
                sb.append(map[i][j]);
            }
            resultMap[i] = sb.toString();
        }
        return resultMap;
    }

    private void printArr(String[] resultMap) {
        for (int i = 0; i < resultMap.length; i++) {
            System.out.println(resultMap[i]);
        }
    }

    public static void main(String[] args) {
        Solution main = new Solution();
        int n = 5;
        int[] arr1 = {9, 20, 28, 18, 11};
        int[] arr2 = {30, 1, 21, 17, 28};

        String[] resultMap = main.solution(n, arr1, arr2);
        main.printArr(resultMap);
    }

}

 

💡 실행결과

charAt()을 이용한 풀이과정 실행 결과

 

 

2️⃣ 두 번째 시도

❓ 풀이과정

1️⃣ 비트 연산자 '|' 를 이용하여 arr1과 arr2의 각 수를 OR연산 후, Integer.toBinaryString()을 통해 연산한 값을 이진수로 변환

더보기

❓ OR 연산자란?

이진 수로 변환했을 때 두 수의 각 자리수가 하나라도 1이면 1로 변환하는 연산
ex ) 11110   = 30

       01001  = 9

      ----------

       11111   = 31

2️⃣ 1️⃣의 결과로 나온 문자열의 길이와 우리가 만들고자 하는 n의 길이 차이만큼 "0"을 반복(.repeat())하여 1️⃣ 문자열 앞에 더해주기

 

✔ 소스코드

public class Solution {
    private String[] solution(int n, int[] arr1, int[] arr2) {
        String[] result = new String[n];
        String bitOper;

        for (int i = 0; i < n; i++) {
            bitOper = Integer.toBinaryString(arr1[i] | arr2[i]).replace("1", "#").replace("0", " ");
            result[i] = " ".repeat(n - bitOper.length()) + bitOper;
        }
        return result;
    }

    private void printArr(String[] resultMap) {
        for (int i = 0; i < resultMap.length; i++) {
            System.out.println(resultMap[i]);
        }
    }

    public static void main(String[] args) {
        Solution main = new Solution();
        int n = 5;
        int[] arr1 = {9, 20, 28, 18, 11};
        int[] arr2 = {30, 1, 21, 17, 28};

        String[] resultMap = main.solution(n, arr1, arr2);
        main.printArr(resultMap);
    }
}

 

💡 실행결과

비트연산을 이용한 풀이 실행 결과

 

 

비트 연산을 통한 풀이가 조금 더 깔끔하고 보기 좋았고, 이를 통해 비트 연산의 편리함을 다시한번 깨달을 수 있는 시간이었다 😊

 

Comments