Algorithm/프로그래머스

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

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

 

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

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

programmers.co.kr

 

2시간 30분 이상 걸렸는데도 못 풀었다... 능지...

openchat function 나누기


sudo 코드

가장 마지막 닉네임으로 해당 uid의 로그를 전부 바꾸면 됨


ArrayList<map(key(uid), String[]())> -> String[]에는 Command 그리고 닉네임
String[] -> 0번쨰는 닉네임을 둬서 계속 바뀌게 그 이후로는 Command를 쌓자


 


1차 시도

String인 map에 order를 줘야하는데 Iterator로 key가져와서 next하고 arraylist의 몇 번째 에 있는 키를 썼느니 그런 과정이 필요해서 접근방법 전환

package com.studyolle;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

public class Main {

	
	
	public static void main(String[] args)
	{
		String[] record = new String[] {"Enter uid1234 Muzi", "Enter uid4567 Prodo","Leave uid1234","Enter uid1234 Prodo","Change uid4567 Ryan"};
		Map<String, String[]> map = new HashMap();
		// extract String
		// 공백 기준 분할 
		ArrayList<Map<String, String[]>> arr = new ArrayList<Map<String,String[]>>();
		// Enum식으로 Enter = 0 Leave = 1 Change = 2
		// nickName만 변수
		for(int i = 0; i < record.length; i++)
		{
			String[] temp;
			// 공백 기준 구분
			temp = record[i].split(" ");
			

			if(temp.length > 2) map.put(temp[1], new String[] {temp[0], temp[2]});
			else 
			{
				map.put(temp[1], new String[] {temp[0]});
			}
			arr.add(map);
			
		}

		for(int i = 0; i < arr.size(); i++)
		{
			
			Iterator<String> keys = map.keySet().iterator();
			String key = keys.next();
			System.out.println(key);
			System.out.println(arr.get(i).get(key)[0]);
		}
		// 어떻게 순서??
	}
}

uid를 기준으로 command를 쌓고 마지막 nickname만 기억하면 될 거 같았지만 들어온 순서를 map으로 되살리기가 어렵다. ArrayList를 사용하면 넣은 순서대로 나올줄 알았지만 map에 order를 줘야한다.

다시 생각해보자

 

2번째 sudo

1. record를 순회하면서 그 문자열이 하고자 하는 command 를 기억해야함
2. uid기준으로 묶음
3. nickname은 마지막 변경사항을 반영

 

2차시도 -> 첫번째 테스트 케이스는 통과하는데 다른건 안 돌아간다.

import java.util.*;

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

        List<String[]> arr = new ArrayList<String[]>();
        Map<String, String> user = new HashMap<String, String>();
        // map으로 갱신해줘서 마지막 갱신값 쓰기
        int resultCount = 0;    // change를 제외하면 totalResult

        for(int i = 0; i < record.length; i++)
        {
            String[] temp = new String[3];

			/*
			command, uid, nickname
			Enter를 base로
			if change -> 결과 로그 생성 X
			if leave nickname 변동 없음
			*/
            temp = record[i].split(" "); // 분할

            if(!temp[0].equals("Change")) // change는 결과 갯수에 상관 없음
            {
                resultCount++;
            }

            if(temp.length > 2) // leave가 아닐 경우 nickName Put으로 갱신
            {
                user.put(temp[1], temp[2]);
            }

            arr.add(temp);  // temp[0] -> command temp[1] -> uid temp[3] -> nickname
        }

        answer = new String[resultCount];

        for(int i = 0; i < answer.length; i++)
        {
            for(int j = 0; j < arr.get(i).length; j++)
            {
                String temp = "";

                if(!arr.get(i)[0].equals("Change")) // change는 추가 없음
               {
                    if(arr.get(i)[0].equals("Enter")) {
                        temp += user.get(arr.get(i)[1]);
                        temp += "님이 들어왔습니다.";
                    }
                    else if(arr.get(i)[0].equals("Leave"))
                    {
                        temp += user.get(arr.get(i)[1]);
                        temp += "님이 나갔습니다.";
                    }
                }
                answer[i] = temp;
            }
        }
        return answer;
    }
}

 

3차 시도 -> 안쪽에 필요없는 for문 버리고 별도의 cnt로 넣어줌 (Jazzo님 코드)

import java.util.*;

class Solution {
    public String[] solution(String[] record) {
        String[] answer;
		
		List<String[]> arr = new ArrayList<String[]>();
		Map<String, String> user = new HashMap<String, String>();
		int resultCount = 0;
		
		for(int i = 0; i < record.length; i++)
		{
			String[] temp = new String[3];
			
			/* 
			command, uid, nickname
			Enter를 base로
			if change -> 결과 로그 생성 X
			if leave nickname 변동 없음
			*/
			temp = record[i].split(" "); // 분할
			
			if(!temp[0].equals("Change")) 
			{
				resultCount++;
			}
			
			if(temp.length > 2)
			{
				user.put(temp[1], temp[2]);
			}
			
			arr.add(temp);
		}
		
		answer = new String[resultCount];
		int ansidx=0;
        
		for(int i = 0; i < record.length; i++)
		{
            String temp = "";

            if(arr.get(i)[0].equals("Change")) continue;
            else {
                if(arr.get(i)[0].equals("Enter")) {
                    temp += user.get(arr.get(i)[1]);
                    temp += "님이 들어왔습니다.";
                }
                else if(arr.get(i)[0].equals("Leave"))
                {
                    temp += user.get(arr.get(i)[1]);
                    temp += "님이 나갔습니다.";
                }
                
                answer[ansidx] = temp;
                ansidx++;
            }
		}
		
		return answer;
    }
}

method 분리

import java.util.*;

class Solution {

    public String[] solution(String[] record) {
        int length = record.length;
        ProcessedChat processedchat = getProcessedChat(record);
        return getAnswer(length, processedchat);
    }

    class ProcessedChat {
        private List<String[]> chatLog;
        private Map<String, String> user;
        private int answerSize;


        public List<String[]> getChatLog() {
            return chatLog;
        }

        public void setChatLog(List<String[]> chatLog) {
            this.chatLog = chatLog;
        }

        public Map<String, String> getUser() {
            return user;
        }

        public void setUser(Map<String, String> user) {
            this.user = user;
        }

        public int getAnswerSize() {
            return answerSize;
        }

        public void setAnswerSize(int answerSize) {
            this.answerSize = answerSize;
        }
        public ProcessedChat(List<String[]> chatLog, Map<String, String> user, int answerSize) {
            this.chatLog = chatLog;
            this.user = user;
            this.answerSize = answerSize;
        }
    }
    /*
    get List<String[]> need what? record
       get user and nickname -> need what? record
       get chatSize -> record
    */
    public ProcessedChat getProcessedChat(String[] record)
    {

        List<String[]> chatLog = new ArrayList<String[]>();
        Map<String, String> user = new HashMap<String, String>();
        int answerSize = 0;

        ProcessedChat processedchat = new ProcessedChat(chatLog, user, answerSize);

        for(int i = 0; i < record.length; i++)
        {
            String[] temp = new String[3];
            temp = record[i].split(" ");
            if(!temp[0].equals("Change")) answerSize++;
            if(temp.length > 2) user.put(temp[1], temp[2]);
            chatLog.add(temp);
        }
        processedchat.setChatLog(chatLog);
        processedchat.setUser(user);
        processedchat.setAnswerSize(answerSize);
        return processedchat;
    }

    public String[] getAnswer(int length, ProcessedChat processedChat) {
        String[] answer = new String[processedChat.getAnswerSize()];
        List<String[]> arr = processedChat.getChatLog();
        Map<String, String> map = processedChat.getUser();

        int idx = 0;
        for (int i = 0; i < length; i++) {
            String temp = "";

            if (arr.get(i)[0].equals("Change")) continue;
            else {
                if (arr.get(i)[0].equals("Enter")) {
                    temp += map.get(arr.get(i)[1]);
                    temp += "님이 들어왔습니다.";
                } else if (arr.get(i)[0].equals("Leave")) {
                    temp += map.get(arr.get(i)[1]);
                    temp += "님이 나갔습니다.";
                }

                answer[idx] = temp;
                idx++;
            }
        }
        return answer;
    }
}