Learn & Run

[Programmers] 오픈 채팅방 (Java, Kotlin) 본문

Algorithm/Programmers

[Programmers] 오픈 채팅방 (Java, Kotlin)

iron9462 2021. 9. 7. 00:16

https://programmers.co.kr/learn/courses/30/lessons/42888

 

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

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

programmers.co.kr

문제

카카오톡 오픈채팅방에서는 친구가 아닌 사람들과 대화를 할 수 있는데, 본래 닉네임이 아닌 가상의 닉네임을 사용하여 채팅방에 들어갈 수 있다. 신입사원인 김크루는 카카오톡 오픈 채팅방을 개설한 사람을 위해, 다양한 사람들이 들어오고, 나가는 것을 지켜볼 수 있는 관리자창을 만드는 문제입니다. 채팅방에 대한 규칙은 아래와 같습니다.

 

채팅방에서 닉네임을 변경하는 방법은 다음과 같이 두 가지이다.

  • 채팅방을 나간 후, 새로운 닉네임으로 다시 들어간다.
  • 채팅방에서 닉네임을 변경한다.

닉네임을 변경할 때는 기존에 채팅방에 출력되어 있던 메시지의 닉네임도 전부 변경된다.

 

접근 아이디어

1. 자료구조 Map 2개를 이용하여 풀이합니다. 1개는 유저가 나가고 들어온 저장 정보, 나머지 1개는 userId에 대한 nickName을 최신 업데이트 해주는 목적으로 사용합니다.

2. 저장과 업데이트가 끝났으면, 나가고 들어온 저장정보를 시간순으로 정렬합니다.

3. 메시지를 작성할 때, userId에 대한 nickName을 꺼내어 조합하여 결과값을 반환합니다.

 

조심해야할 점

파라미터로 들어오는 record는 최대 10만개이기 때문에 시간복잡도를 생각하며 코드를 구성해야 합니다.

 

 

- Java

import java.util.*;

class Solution {
    
    public String[] solution(String[] record) {

        Map<Integer, Info> map = new HashMap<>();
        Map<String, String> nameMap = new HashMap<>();

        for (int index = 0; index < record.length; index++) {
            String[] subRecord = record[index].split(" ");
            String access = subRecord[0];
            String userId = subRecord[1];
            String nickName;

            if (subRecord.length == 3) {
                nickName = subRecord[2];

                //userMap에 등록된 userId가 들어온경우, Change인 경우 모두 nickName을 가장 최근꺼로 변환
                nameMap.put(userId, nickName);

                //Change일 때는 아이디만 변경
                if (!access.equals("Change")) {
                    map.put(index, new Info(index, userId, nickName, access));
                }
            } else {
                //Leave인 경우는 nickName은 빈값으로 채움
                map.put(index, new Info(index, userId, "", access));
            }
        }

        String[] result = new String[map.size()];
        List<Info> list= new ArrayList<>();
        
        Iterator<Integer> iterator = map.keySet().iterator();
        while(iterator.hasNext()) {
            list.add(map.get(iterator.next()));
        }

        //채팅방에 들어온 순서대로 정렬하기
        list.sort(Comparator.comparingInt(o -> o.index));
        
        for(int i=0; i<result.length; i++ ) {
            Info info = list.get(i);
            result[i] = info.access.equals("Enter") ? nameMap.get(info.userId) + "님이 들어왔습니다." : nameMap.get(info.userId) + "님이 나갔습니다.";
        }

        return result;
    }

    static class Info {
        int index;
        String userId;
        String nickName;
        String access;

        Info(int index, String userId, String nickName, String access) {
            this.index = index;
            this.userId = userId;
            this.nickName = nickName;
            this.access = access;
        }
    }
}

 

 

- Kotlin

import java.util.*;

class Solution {

    fun solution(record: Array<String>): Array<String> {
        val map = HashMap<Int, Info>()
        val nameMap = HashMap<String, String>()
        for (index in record.indices) {
            val subRecord = record[index].split(" ")

            val access = subRecord[0]
            val userId = subRecord[1]
            var nickName: String
            if (subRecord.size == 3) {
                nickName = subRecord[2]

                //userMap에 등록된 userId가 들어온경우, Change인 경우 모두 nickName을 가장 최근꺼로 변환
                nameMap[userId] = nickName

                //Change일 때는 아이디만 변경
                if (access != "Change") {
                    map[index] = Info(index, userId, nickName, access)
                }
            } else {
                //Leave인 경우는 nickName은 빈값으로 채움
                map[index] = Info(index, userId, "", access)
            }
        }

        return ArrayList(map.entries)
            .map { it.value }
            .sortedBy { it.index } //채팅방에 들어온 순서대로 정렬하기
            .map { nameMap[it.userId] + if ( it.access == "Enter" ) "님이 들어왔습니다." else "님이 나갔습니다."
            }.toTypedArray()
    }

    class Info(
        val index: Int,
        val userId: String,
        val nickName: String,
        val access: String
    )
}

 

 

좌(Java 채점 결과), 우(Kotlin 채점 결과)