코딩 테스트 [프로그래머스] - [3차] 압축

유의선·2024년 3월 6일

문제 링크

Key와 Value로 값을 저장하는 특징을 가진 HashMap을 사용하여 문제를 풀었다.


전체 코드는 다음과 같다.

import java.util.*;

class Solution {
    public int[] solution(String msg) {

        ArrayList<Integer> arrayList = new ArrayList<>();
        HashMap<String, Integer> hashMap = new HashMap<>();
        
        for(int i = 65; i <= 90; i++){
            hashMap.put(Character.toString((char)i), i - 64);
        }
        
        while(msg.length() > 0){
            int len = msg.length();
            int count = 1;
            String now = msg.substring(0, count);
            
            if(len == 1){
                arrayList.add(hashMap.get(now));
                break;
            }
            
            while(true){
                boolean haveKey = hashMap.containsKey(now);
                
                if(haveKey){
                    if(msg.equals(now)){
                        arrayList.add(hashMap.get(now));
                        msg = msg.substring(count, msg.length());
                        break;
                    }else{
                        count++;
                        now = msg.substring(0, count);
                    }
                }else{
                    hashMap.put(now, hashMap.size() + 1);
                    
                    count--;
                    now = msg.substring(0, count);
                    arrayList.add(hashMap.get(now));
                    
                    msg = msg.substring(count, msg.length());
                    break;
                }
            }
        }
        
        int[] answer = new int[arrayList.size()];
        for(int i = 0; i < arrayList.size(); i++){
            answer[i] = arrayList.get(i);
        }
        
        return answer;
    }
}

먼저 정답을 저장할 ArrayList와 사전 역할을 할 HashMap을 선언하였고,
HashMap에 알파벳 A ~ Z를 key로, 1 ~ 26을 value로 저장하였다.

        ArrayList<Integer> arrayList = new ArrayList<>();
        HashMap<String, Integer> hashMap = new HashMap<>();
        
        for(int i = 65; i <= 90; i++){
            hashMap.put(Character.toString((char)i), i - 64);
        }

주어진 문자열 msg의 길이가 0이 될때까지 이하의 내용을 반복한다.

        while(msg.length() > 0){
            ...
        }

먼저 msg의 길이와,
msg에서 가져온 현재 문자열 now와,
now가 msg에서 어느 위치를 가리키는 지를 알려주는 count를 선언하였다.
msg의 제일 처음부터 시작하므로 now가 msg.substring(0, 1)이 되도록 만들었다.

			int len = msg.length();
            int count = 1;
            String now = msg.substring(0, count);

만약 이 시점에서 msg의 길이가 1이라면 이 이상 단어를 탐색할 수 없으므로
key값으로 now를 가진 value를 사전인 hashMap 에서 찾아 정답 리스트arrayList에 넣고 반복문을 종료한다.

            if(len == 1){
                arrayList.add(hashMap.get(now));
                break;
            }

그 외의 경우에는
먼저 반복문을 만들고, 사전 안에 now가 있는지 확인한다.

			while(true){
                boolean haveKey = hashMap.containsKey(now);
                
                ...
            }

만약 사전 안에 now가 있다면

먼저 now의 길이가 지금 문자열 msg와 똑같은지 확인한다.

만약 같다면 이 단어로 문장이 끝나므로, 사전에서 지금 단어(now)의 value 값을 찾아 정답 리스트(arrayList)에 추가한다.
그 후 msg에서 지금 사전에 추가한 단어만큼 삭제하고, 반복문을 빠져나온다.

            while(true){
                boolean haveKey = hashMap.containsKey(now);
                
                if(haveKey){
                    if(msg.equals(now)){
                        arrayList.add(hashMap.get(now));
                        msg = msg.substring(count, msg.length());
                        break;
                    }else{
                    
                        ...
                        
                    }
                }

만약 길이가 다르다면 아직 더 탐색할 수 있다는 뜻이므로
count를 늘리고 그 값으로 msgsubstring하여 now의 길이를 하나 늘린다.

그 후 반복문에 의해 사전 안에 now가 있는지 다시 확인하게 된다.

            while(true){
                boolean haveKey = hashMap.containsKey(now);
                
                if(haveKey){
                    if(msg.equals(now)){
                        
                        ...
                        
                    }else{
                        count++;
                        now = msg.substring(0, count);
                    }
                }

만약 사전 안에 now가 없다면 지금 단어를 사전에 추가하고, 지금 단어보다 하나 짧은 단어의 value값을 정답에 추가해줘야 한다.

현재 now를 사전에 추가한다.
key 값을 now로, value는 (현재 사전의 길이+1) 로 추가한다.

그 후 count값을 1 줄인 값으로 msgsubstringnow값의 value를 사전에서 찾아 정답 리스트에 집어넣는다.

마지막으로 msg에서 지금 사전에 추가한 단어만큼 삭제하고, 반복문을 빠져나온다.

            while(true){
                boolean haveKey = hashMap.containsKey(now);
                
                if(haveKey){
                    if(msg.equals(now)){
                        
                        ...
                        
                    }
                }else{
                    hashMap.put(now, hashMap.size() + 1);
                    
                    count--;
                    now = msg.substring(0, count);
                    arrayList.add(hashMap.get(now));
                    
                    msg = msg.substring(count, msg.length());
                    break;
                }
            }

msg에서 단어를 확인하며, 확인한 단어는 msg에서 삭제하도록 하였으므로 모든 단어를 다 확인하면 msg의 길이는 0이 되어 반복문을 빠져나오게 된다.

그 후엔 정답을 저장한 arrayList의 내용을 answer[]배열에 저장하고 반환한다.

        int[] answer = new int[arrayList.size()];
        for(int i = 0; i < arrayList.size(); i++){
            answer[i] = arrayList.get(i);
        }
        
        return answer;

0개의 댓글