본문 바로가기

알고리즘/프로그래머스

[JAVA] 프로그래머스 - 오픈 채팅방

문제 내용

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

 

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

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

programmers.co.kr

 

문제내용은 간단하다 채팅방을 들어오고 나가는 사람들을 기록하고 마지막에 출력하는것.

근데 닉네임 변경조건이 나갔다 다시 들어오면서 바꾸거나 채팅방안에서 바꿀수 있다고 한다.

 


문제 접근 방법

첫번째 방법은 오로지 배열만 이용해서 풀었는데 배열을 만들고 연산하는 과정이 다른 코드에 비해 복잡해서 그런지 런타임 에러와 시간초과가 나면서 틀리게됐다.

 

그래서 새로운 방법을 생각하던 도중...전에 문자열 문제를 풀었을때처럼 해시맵을 이용하면 어떨까 생각을했다.

처음엔 key에 ID , value에 Nickname & command 를 알려주는 클래스 객체를 넣을까 생각을 했는데 아직 실력이 부족해서 하다가 안풀려서 다른 사람들 풀이를 참고했다.

 

내가 생각했던 방법이 더 객체지향적이라고 생각하지만 간단해 보이는 풀이로 다시 풀었다.

 

풀이 방법은 간단하다.

for문을 이용해 한번 순회를 하면서 들어오고 나가는 사람들의 ID를 List에 기록하고,

HashMap에 ID와 Nickname을 key와 value로 저장해준다.

 

순회가 끝나면 List의 요소값을 뽑고 ID를 Map에 저장된 value 값으로 바꿔주기만 하면된다.

 

한마디로 일단 쭉 저장하고 바뀐 아이디들은 마지막에 쭉 바꿔주는 작업이다.

 

아래를보고 망한코드와 풀이를 보자.

 


풀이

정답 코드

	public static String[] solution(String[] record) {
		ArrayList<String> chatList = new ArrayList<String>();
		HashMap<String, String> userMap = new HashMap<String, String>();
		String[] com = new String[3]; 
		int cnt = 0;
		
		for(int i=0; i<record.length; i++) {
			com = record[i].split(" ");
			String uid = com[1];
			String userNick = "";
			
			if(!com[0].equals("Leave")) userNick = com[2];
			
			switch (com[0]) {
			case "Enter":
				chatList.add(uid+"님이 들어왔습니다.");
				userMap.put(uid, userNick);
				break;
			case "Leave":
				chatList.add(uid+"님이 나갔습니다.");
				break;
			case "Change":
				userMap.put(uid, userNick);
				cnt++;
				break;
			}
		}
		
		String[] ans = new String[record.length-cnt];
		int i = 0;
		
		for(String chat:chatList) {
			int uidIdx = chat.indexOf("님");
			String start = chat.substring(0,uidIdx);
			String end = chat.substring(uidIdx, chat.length());
			
			ans[i++] = start.replace(start, userMap.get(start))+end;
		}
		return ans;
	}

 


실패 코드

public static String[] solution(String[] record) {
		String[] com = new String[3];
		String[] uid = new String[record.length];
		int cnt = 0;
		for(int i=0; i<record.length; i++) {
			com = record[i].split(" ");
			if(com[0].equals("Enter")||com[0].equals("Leave")) cnt++;
		}
		String[] ans = new String[cnt];
		String[] result = new String[cnt];
		
		for(int i=0; i<record.length; i++) {
			com = record[i].split(" ");
			
			if(com[0].equals("Enter")) {
				ans[i]=com[2];
				uid[i]=com[1];
				result[i] = "님이 들어왔습니다.";
				for(int j=0; j<uid.length-1; j++) {
					if(uid[i].equals(uid[j])) {
						ans[j] = ans[i];
						
					}
				}
			}else if(com[0].equals("Leave")){
				uid[i] = com[1];
				result[i]="님이 나갔습니다.";
				for(int j=0; j<uid.length-1; j++) {
					if(uid[i].equals(uid[j])) {
						ans[i] = ans[j];
					}
				}
			}else {
				uid[i] = com[1];
				String change = com[2];
				for(int j=0; j<uid.length-1; j++) {
					if(uid[i].equals(uid[j])) {
						ans[j] = change;
					}
				}
			}
		}
		
		for(int i=0; i<ans.length; i++) {
			result[i] = ans[i]+result[i];
		}
		
		return result;
	}

 


마치며

코드를 보면 알겠지만 List와 HashMap을 이용한 정답코드가 훨씬 알아보기 쉽다..(심지어 밑에 코드는 틀린코드 ㅠ)

첫번째 방법이 틀리고 HashMap을 써야봐야 겠다는 생각을하고 삽질을 해서 그런지 아직은 HashMap에 대한 활용이 미숙하다고 느꼈다.