Coding Test/프로그래머스

[201111] 오픈채팅방 - 2019 KAKAO BLIND RECRUITMENT(level2)

csmoon1010 2020. 11. 11. 14:34

0. 문제 유형 : 적절한 자료구조 사용(HashMap)

1. 문제 이해

(1) 주요 요구사항

- record 배열 : 유저의 들어오기, 나가기, 닉네임 변경을 기록한 배열

1. 입장 : Enter [유저 아이디] [닉네임] → "[닉네임]님이 들어왔습니다." 출력
2. 퇴장 : Leave [유저 아이디] → "[닉네임]님이 나갔습니다." 출력
3. 변경 : Change [유저 아이디] [닉네임] → 해당 유저 아이디의 닉네임이 변경

- 닉네임의 변경

1. 유저가 채팅방에 있을 때 : 변경 기록이 record에 들어감
2. 유저가 채팅방을 나가고 변경 후 다시 들어올 때
▶ 기존 채팅방에 출력되어 있던 메시지의 닉네임도 전부 변경

 

(2) 제한사항

- record의 길이는 1이상 100,000 이하

- 유저 아이디, 닉네임의 길이는 1이상 10이하

- record : 각 단어는 공백 구분. 대소문자, 숫자로 이루어짐.

- 첫 단어 : Enter, Leave, Change 중 하나

- **유저 아이디, 닉네임 : 대소문자 구별

- 채팅방에서 나간 유저가 닉네임을 변경하는 등 잘못 된 입력은 주어지지 않음.

- **채팅방 밖에서 변경한 기록은 record에 남지 않는다. (실수했던 부분)

 

 

2. 전략

(1) record의 요소 분리 : String 클래스의 split(" ") 이용

- record의 각 요소에 대해서 split(" ") → 길이가 2 혹은 3인 배열(str)

- 각 요소의 역할을 분리

1. str[0] : Enter/Leave/Change - 액션을 구분해주는 역할
2. str[1] : 유저 아이디 - HashMap의 key
3. str[2] : 닉네임 - HashMap의 value

(2) 유저 아이디와 닉네임을 관리 : HashMap & ArrayList<String[]> 이용

① HashMap<String, String> nickMap : 유저 아이디를 key, 닉네임을 value로 하는 HashMap

- 액션이 Enter : HashMap에 key가 없으면 put, key가 있다면 replace(※ 외부에서 변경했을 수 있으므로)

- 액션이 Leave : HashMap의 변경 사항 없음

- 액션이 Change : HashMap의 key값에 따른 value를 replace

② ArrayList<String[]> result: 액션의 결과를 담기 위한 자료구조

- 요소로는 길이가 2인 String 배열 : {유저 아이디, 액션}

- Enter인 경우는 "님이 들어왔습니다.", Leave인 경우는 "님이 나갔습니다." → String[]으로 변경할 때 유용

▶ String[]으로 변경 시, (nickMap에서 result에 담긴 유저 아이디에 해당하는 value)로 넣어준다!

 

 

3. 참고 사항

(1) 대소문자 구분

- 첫 단어는 Enter, Leave, Change 중에 하나이지만 대소문자 구별에 대한 언급이 없음

→ 대소문자 구분없이 확인할 필요!!

→ str[0].equalsIgnoreCase("Enter")

cf> (String).toLowerCase() / String.toUpperCase() : String을 대/소문자로 변경

 

 

4. 코드

import java.util.*;

class Solution {
    public String[] solution(String[] record) {
        String[] answer = {};
        HashMap<String, String> nickMap = new HashMap<>();
        ArrayList<String[]> result = new ArrayList<>();
        for(String s : record){
            String[] str = s.split(" ");
            if(str[0].equalsIgnoreCase("Enter")){
                if(!nickMap.containsKey(str[1]))nickMap.put(str[1], str[2]);
                else nickMap.replace(str[1], str[2]);
                result.add(new String[]{str[1], "님이 들어왔습니다."});
            }
            else if(str[0].equalsIgnoreCase("Leave"))
                result.add(new String[]{str[1], "님이 나갔습니다."});
            else
                nickMap.replace(str[1], str[2]);
        }
        
        answer = new String[result.size()];
        for(int i = 0; i < result.size(); i++){
            String[] target = result.get(i);
            answer[i] = nickMap.get(target[0]) + target[1];
        }
        return answer;
    }
}