[201111] 오픈채팅방 - 2019 KAKAO BLIND RECRUITMENT(level2)
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;
}
}