오픈채팅방

문제

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

신입사원인 김크루는 카카오톡 오픈 채팅방을 개설한 사람을 위해, 다양한 사람들이 들어오고, 나가는 것을 지켜볼 수 있는 관리자창을 만들기로 했다. 채팅방에 누군가 들어오면 다음 메시지가 출력된다.
[닉네임]님이 들어왔습니다.

채팅방에서 누군가 나가면 다음 메시지가 출력된다.
[닉네임]님이 나갔습니다.

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

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

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

제한사항

  • record는 다음과 같은 문자열이 담긴 배열이며, 길이는 1 이상 100,000 이하이다.
  • 다음은 record에 담긴 문자열에 대한 설명이다.
    • 모든 유저는 [유저 아이디]로 구분한다.
    • [유저 아이디] 사용자가 [닉네임]으로 채팅방에 입장 - “Enter [유저 아이디] [닉네임]” (ex. “Enter uid1234 Muzi”)
    • [유저 아이디] 사용자가 채팅방에서 퇴장 - “Leave [유저 아이디]” (ex. “Leave uid1234”)
    • [유저 아이디] 사용자가 닉네임을 [닉네임]으로 변경 - “Change [유저 아이디] [닉네임]” (ex. “Change uid1234 Muzi”)
    • 첫 단어는 Enter, Leave, Change 중 하나이다.
    • 각 단어는 공백으로 구분되어 있으며, 알파벳 대문자, 소문자, 숫자로만 이루어져있다.
    • 유저 아이디와 닉네임은 알파벳 대문자, 소문자를 구별한다.
    • 유저 아이디와 닉네임의 길이는 1 이상 10 이하이다.
    • 채팅방에서 나간 유저가 닉네임을 변경하는 등 잘못 된 입력은 주어지지 않는다.

입출력 예

record result
[“Enter uid1234 Muzi”, “Enter uid4567 Prodo”,”Leave uid1234”,”Enter uid1234 Prodo”,”Change uid4567 Ryan”] [“Prodo님이 들어왔습니다.”, “Ryan님이 들어왔습니다.”, “Prodo님이 나갔습니다.”, “Prodo님이 들어왔습니다.”]

답안 1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import java.util.*;

class Solution {
public String[] solution(String[] record) {
ArrayList<String> chatLog = new ArrayList<String>(); // log를 저장하는 ArrayList 선언
String[] tmp = new String[3]; // 문자열로 들어온 record를 분개하기 위한 로직 추가
HashMap<String, String> user = new HashMap<String, String>(); // 사용자 목록을 저장하는 HashMap 선언

for(String rec : record){
tmp = rec.split(" ");
switch(tmp[0]){
case "Enter":
user.put(tmp[1], tmp[2]);
chatLog.add(tmp[1] + "님이 들어왔습니다.");
break;
case "Leave":
chatLog.add(tmp[1] + "님이 나갔습니다.");
user.remove(tmp[1]);
break;
case "Change":
user.put(tmp[1], tmp[2]);
break;
}
}

int idx = 0;
String[] answer = new String[chatLog.size()];
for(String log : chatLog){
int endOfId = log.indexOf("님");
String userId = log.substring(0, endOfId);

answer[idx++] = log.replace(userId, user.get(userId));
}

return answer;
}

}

채점 결과

정확성: 6.3
합계: 6.3 / 100.0

테스트 케이스 1 / 16번 제외 런타임 에러 발생

2차 답안

user.remove(tmp[1]); 제거

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import java.util.*;

class Solution {
public String[] solution(String[] record) {
ArrayList<String> chatLog = new ArrayList<String>(); // log를 저장하는 ArrayList 선언
String[] tmp = new String[3]; // 문자열로 들어온 record를 분개하기 위한 로직 추가
HashMap<String, String> user = new HashMap<String, String>(); // 사용자 목록을 저장하는 HashMap 선언

for(String rec : record){
tmp = rec.split(" ");
switch(tmp[0]){
case "Enter":
user.put(tmp[1], tmp[2]);
chatLog.add(tmp[1] + "님이 들어왔습니다.");
break;
case "Leave":
chatLog.add(tmp[1] + "님이 나갔습니다.");
//user.remove(tmp[1]);
break;
case "Change":
user.put(tmp[1], tmp[2]);
break;
}
}

int idx = 0;
String[] answer = new String[chatLog.size()];
for(String log : chatLog){
int endOfId = log.indexOf("님");
String userId = log.substring(0, endOfId);

answer[idx++] = log.replace(userId, user.get(userId));
}

return answer;
}

}

채점 결과

정확성: 100.0
합계: 100.0 / 100.0

user.remove(tmp[1]); 제거
해당 요소를 제거하게 되면 다음에 해당 id로 Enter 하지 않게 된다면
userId 값을 user에서 찾을 수 가 없기 때문에 에러가 발생합니다.