PS/Programmers

[level1, 비트 연산] [1차] 비밀지도

git-sun 2023. 3. 27. 23:59

1. 문제

 

 

 

 

 

2. 문제 해결 논리

1. 문제 이해

  • 주어진 것
    • int n    //지도의 한 변의 쿠기
    • int[] arr1    //하나의 지도인 정수 배열
    • int[] arr2    //다른 하나의 지도인 정수 배열
  • 요구되는 것
    • String[] answer    //두 지도를 합쳐 "#"과 " "로 이루어진 최종 지도인 문자열 배열

2. 데이터 구조 결정

  • Integer 클래스의 toBinaryString 메서드, String 클래스의 format, replaceAll 메서드 사용
  • 반복문, StringBuilder, 쉬프트 연산자 사용

3. 알고리즘 설계

  • toBinaryString, format, replaceAll 메서드
    1. Integer.toBinaryString 메서드로 2진법 문자열로 변환
    2. String.format 메서드로 한 변의 크기만큼 2진법 문자열에 공백 추가
    3. String.replaceAll 메서드로 문자열 중 1은 #으로, 0은 공백으로 대체
  • 반복문, StringBuilder, 쉬프트 연산자 사용
    1. 반복문을 통해서 String에 연산 결과가 담긴 StringBuilder를 저장
    2. 반복문을 통해서 1을 n번 쉬프트 이동
    3. arr1과 arr2의 이진수가 쉬프트 이동된 1과 같은 자리에 1이 동시에 존재하는지 확인
    4. 존재하면 "#", 존재하지 않으면 " " 추가 

 

 

 

 

 

 

3. 코드 구현

3-1. toBinaryString, format, replaceAll 메서드

class Solution {
    public String[] solution(int n, int[] arr1, int[] arr2) {
        //n이 5라면
        String[] answer = new String[n];
		
        //주어진 정수 배열을 하나씩 순회
        for (int i = 0; i < n; i++) {
            //같은 인덱스에서 두 원소를 비트 합연산( | )
            String row = Integer.toBinaryString(arr1[i] | arr2[i]);
            
            //지도의 크기만큼 왼쪽에 공백 추가
            //n이 5라면 ("%5s", row)와 같다
            //row가 1001이라면 "%5s"에 의해 1001이 오른쪽 정렬되면서 맨 왼쪽에는 공백이 추가됨
            //즉, " 1001"로 다섯자리의 문자열로 변환됨
            row = String.format("%" + n + "s", row);
            
            // 1을 벽('#')으로 대체
            row = row.replaceAll("1", "#");
            // 0을 공백(' ')으로 대체
            row = row.replaceAll("0", " ");
            
            //반환할 문자열 배열 answer의 원소로 추가
            answer[i] = row;
        }

        return answer;
    }
}

 

 

 

 

 

 

3-2. 반복문, StringBuilder, 쉬프트 연산자

class Solution {
    public String[] solution(int n, int[] arr1, int[] arr2) {
        String[] answer = new String[n];
		
        //answer에 i=0부터 순회하며 문자열 추가
        for (int i = 0; i < n; i++) {
        	
            StringBuilder sb = new StringBuilder();
			
            //이진수의 제일 앞자리부터 순회하기 위해 j = n-1에서 시작
            //n-1 >= j >= 0 이므로 총 n번 순회
            //n이 5라면, j = 4,3,2,1,0으로 순회
            for (int j = n - 1; j >= 0; j--) {
            
            	//j가 4라면 1을 왼쪽으로 네 번 쉬프트 이동하여 bit에 저장
                //-> 10000
                //4만큼 쉬프트 이동했기 때문에 bit에는 1이 맨 앞자리에만 존재
                int bit = (1 << j);
                
                //arr1이나 arr2가 bit와 동일한 자리에 1이 존재한다면
                if ((arr1[i] & bit) > 0 || (arr2[i] & bit) > 0) {
                    sb.append("#");  //"#" 벽 추가
                    
                //arr1과 arr2 둘 다 동일한 자리에 1이 없다면
                } else {
                    sb.append(" ");  //" " 공백 추가
                }
            }
			
            //작업이 완료된 StringBuilder를 answer의 원소로 저장
            answer[i] = sb.toString();
        }

        return answer;
    }
}

 

 

 

 

 

 

 

 

* Reference

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

 

프로그래머스

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

programmers.co.kr

 

반응형