만족은 하되 안주하지는 말자

기록해야 기억한다

카테고리 없음

[JAVA] 오픈채팅방

D36choi 2022. 2. 21. 16:13
728x90

문제

https://programmers.co.kr/learn/courses/30/lessons/42888?language=java 

 

코딩테스트 연습 - 오픈채팅방

오픈채팅방 카카오톡 오픈채팅방에서는 친구가 아닌 사람들과 대화를 할 수 있는데, 본래 닉네임이 아닌 가상의 닉네임을 사용하여 채팅방에 들어갈 수 있다. 신입사원인 김크루는 카카오톡 오

programmers.co.kr

내 풀이

import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;

class Solution {
    
    private static String WELCOME_MSG = "님이 들어왔습니다.";
    private static String GOODBYE_MSG = "님이 나갔습니다.";
    
    
    public String[] solution(String[] record) {
        List<String> answer = new ArrayList<String>();
        Map<String,String> users = new HashMap<>();
        List<String[]> results = new ArrayList<String[]>();
        for (String log : record) {
            String[] commands = log.split(" ");
            switch(commands[0]) {
                case "Enter":
                    this.updateUsers(users,commands);
                    results.add(commands);
                    break;
                case "Change":
                    this.updateUsers(users,commands);
                    break;
                case "Leave":
                    results.add(commands);
                    break;
            }
        }
        for (String[] result: results) {
            answer.add(this.getMessage(result,users));
        }
        return answer.toArray(new String[answer.size()]);
    }
    
    private void updateUsers(Map<String,String> users, String[] commands) {
        String uid = commands[1];
        String name = commands[2];
        users.put(uid, name);
    }
    private String getMessage (String[] result, Map<String,String> users) {
        String type = result[0];
        String uid = result[1];
        StringBuilder message = new StringBuilder();
        message.append(users.get(uid));
        
        if ("Enter".equals(type)) {
            message.append(this.WELCOME_MSG);
        } else {
            message.append(this.GOODBYE_MSG);
        }
        return message.toString();
    }
}

모든 메시지들을 순회해 Enter, Change 인 경우에는 uid : name 형태의 users Map을 업데이트해 ID 마다의 사용자 닉네임을 업데이트한다.

어차피 사용자에게 보여질 최종 메시지들만 보여주면 되니까 순간순간의 닉네임은 필요가 없다. 중요한 건 최종상태의 닉네임들이기 때문이다.

 

Enter, Leave에 대해서는 results 리스트에 담아놓는다. 최종 메시지 출력때 필요한 커맨드가 그 두 개이기 때문이다.

Enter냐, Leave냐에 따라 적절한 문자열을 붙여주고 uid에 따라 앞에 닉네임을 설정해준다.

이를 array로 변형해 반환한다.

알게 된 것

이번엔, 가독성을 위해 switch case 문을 활용했다. 확실히 읽기 편한 코드가 되었다.

 

피드백

String.format(String format, Object ...args); 를 활용하면 반복되는 문자열을 만들기 좋다.

 

    private String getMessage (String[] result, Map<String,String> users) {
        String type = result[0];
        String uid = result[1];
        StringBuilder message = new StringBuilder();
        message.append(users.get(uid));
        
        if ("Enter".equals(type)) {
            message.append(this.WELCOME_MSG);
        } else {
            message.append(this.GOODBYE_MSG);
        }
        return message.toString();
    }
    
    // 아래로 변형 가능
    private static String WELCOME_MSG = "%s님이 들어왔습니다.";
    private static String GOODBYE_MSG = "%s님이 나갔습니다.";
    
    private String getMessage (String[] result, Map<String,String> users) {
        String type = result[0];
        String uid = result[1];
        return String.format("Enter".equals(type) ? WELCOME_MSG : GOODBYE_MSG, users.get(uid));
    }

append 혹은 concat 과정이 필요없이, static 문자열을 활용해 특정 위치에 유저네임을 대치해서 문자열을 리턴할 수 있다.

 

문자열 변형이 많은 문제에서 자주 활용하면 좋겠다.