본문 바로가기
카테고리 없음

[프로그래머스] Lv.2 오픈채팅방 JAVA 풀이

by Poorm 푸름 2023. 11. 23.

문제 Lv.2 오픈채팅방 

 :  오픈채팅방에서는 닉네임을 사용

    누군가 들어오면 "[닉네임]님이 들어왔습니다." 라고 출력

    누군가 나간다면 "[닉네임]님이 나갔습니다." 라고 출력

 

 :  닉네임 변경 방법

  1. 채팅방 나가고 새로운 닉네임으로 다시 들어오기
  2. 채팅방에서 닉네임 변경하기

 

  • 닉네임이 변경되면 기존 메시지의 닉네임도 전부 변경
  • 닉네임 중복가능
  • 닉네임을 변경한 기록이 담긴 문자열 배열 = record
  • 모든 기록이 처리된 후 최종 출력 결과를 문자열 배열 행태로 return 한다

 

 :  < record >

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

 

 :  < 입출력 예시 >

 

  • record : ["Enter uid1234 Muzi", "Enter uid4567 Prodo", "Leave uid1234"]
  • result : ["Muzi 님이 들어왔습니다.", "Prodo님이 들어왔습니다.", "Muzi님이 나갔습니다."]

 

 

[문제 접근]

 

< String[] spt = record[i].split(" ") >

  • 문자열 중 첫번째 값들 (Enter, Leave) 로 비교해서 출력하기
    Change는 닉네임이 바뀔뿐 다시 출력하지는 않으니 무시한다

  • 공백 단위로 문자를 끊기 위해서는 split(" ")이 필요할 듯

  • 이때 중요한건 record 자체가 통으로 연결된 문자열이 아닌 배열이라는 것이다
    그래서 index를 정해놓고 하나하나 들어가 문자열을 분해해야 한다
    즉 record는 for문을 통해서 [i]라는 index를 달아주기

 

 < Map<String, String>map = new HashMap<>() >

 

  • id를 먼저 찾고 닉네임을 연결하는 모습이  마치 key값과 value값의 느낌같다 
    대신 record를 보면 Leave로 시작하는 문장은 닉네임이 없다 
    고로 record 길이가 3 (=상태, id, 닉네임)인 경우만 map에 value를 추가해줄 수 있다
  • 같은 키 값에 여러 value라면 덮어씌워져 최근에 저장된 value만 살아남는다

 

 < ArrayList<String> answer = new ArrayList<>() >

 

  • 배열로 출력하라고 했는데 배열 크기 정하기가 귀찮아서 가변적인 ArrayList 설정

  • 반환값이 ArrayList이므로 main 메서드 형태도 String[] 가 아닌 List<String>으로 변경

 

 

[코드]

import java.util.*;

class Solution {
    public List<String> solution(String[] record) {
       
        Map<String, String> map = new HashMap<>();
        ArrayList<String> answer = new ArrayList<>();
               
        for(int i = 0; i<record.length; i++){
            String[] spt =record[i].split(" ");
            if(spt.length == 3)
                map.put(spt[1], spt[2]);
        }
        
        for(int i = 0; i<record.length; i++){
           String[] spt =record[i].split(" ");
      
            switch(spt[0]){
                case "Enter":
                    answer.add(map.get(spt[1])+"님이 들어왔습니다.");
                break;
          
                case "Leave":
                    answer.add(map.get(spt[1])+"님이 나갔습니다.");
                break;
            }
        }                   
        return answer;
    }
}

 

 :  public List<String> solution(String[] record) {  리턴값이 ArrayList이므로 형식 똑같이 맞춰주기
      

 :  Map<String, String> map = new HashMap<>();  id를 key로 삼아 닉네임을 value로 저장하는 map
    ArrayList<String> answer = new ArrayList<>();  출력할 배열
              

 :  for(int i = 0; i<record.length; i++){  
        String[] spt =record[i].split(" ");  record의 i번째 문자를 공백 단위로 구분해서 spt 배열에 저장
        if(spt.length == 3)  단, spt의 길이가 3일 경우에만 map에 값을 추가한다 (Leave를 예외로)
            map.put(spt[1], spt[2]);  key = spt[1] = id  /  value = spt[2] = 닉네임
    }
        
 :  for(int i = 0; i<record.length; i++){  위의 for문과 하나로 합치면 변경 전, 후 닉네임이 둘 다 떠서 따로 구분
       String[] spt =record[i].split(" ");  한 번 더 써줘야 한다 아래에서 쓸거라
      
        switch(spt[0]){  0번째 문자로 비교
           case "Enter":
              answer.add(map.get(spt[1])+"님이 들어왔습니다.");  spt[1] = key, value( = spt[2] = 닉네임) 
           break;
          
           case "Leave":
               answer.add(map.get(spt[1])+"님이 나갔습니다.");  spt[1] = key, value( = spt[2] = 닉네임) 

           break;
           }
   }                   
      

 :  return answer;  answer 배열 출력    
 

 

 

[시간 복잡도]

 

for문을 2개 사용

for문 둘 다 record만큼 돌기 때문에 O(2N)

즉, 시간복잡도는 O(N) 이다

 

 

 

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

* 독학으로 익히는 코딩이라 틀린 것이 있을 수 있습니다. 오류가 있다면 댓글을 통해 알려주세요. 감사합니다. *