본문 바로가기
Blog/TIL

[240611] 해시맵 활용

by 코젼 2024. 6. 11.
728x90
반응형

🔶코딩테스트


목차

    / 오늘의 TIL /


    코딩테스트

    해시 1

    • 최종적으로 구하고자 하는 것
    • 입력 값 중 수정되지 않는 것
    • 입력 값 중 수정되는 것
      • 입력 값이 수정될 때 영향 받는 것
      • 입력 값이 수정되는 조건

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

    리팩토링

    Enter == Change 동일한 명령어로 취급해도 된다.

    명령어에 관한 문자열은 해쉬맵으로 처리할 수 있다.

    더보기
    import java.util.*;
    
    class Solution {
            /**
         * @param record 채팅방에 들어오고 나가거나, 닉네임을 변경한 기록이 담긴 문자열 배열
         * @return 최종적으로 방을 개설한 사람이 보게 되는 메시지
         */
        public static String[] solution(String[] record) {
    
            HashMap<String, String> msg = new HashMap<>();
            msg.put("Enter", "님이 들어왔습니다.");
            msg.put("Leave", "님이 나갔습니다.");
    
            HashMap<String, String> uid = new HashMap<>();
    
            for (String s : record) {
                String[] cmd = s.split(" ");
                if (cmd.length == 3) { //Enter 또는 Change인 경우
                    uid.put(cmd[1], cmd[2]); //명령어, user id
                }
            }
    
            ArrayList<String> answer = new ArrayList<>();
    
            for (String s : record) {
                String[] cmd = s.split(" ");
                if (msg.containsKey(cmd[0])) {
                    answer.add(uid.get(cmd[1]) + msg.get(cmd[0]));
                }
            }
            return answer.toArray(new String[0]);
        }
    }

    풀이

    더보기
    import java.util.*;
    
    class Solution {
        /**
         * @param record 채팅방에 들어오고 나가거나, 닉네임을 변경한 기록이 담긴 문자열 배열
         * @return 최종적으로 방을 개설한 사람이 보게 되는 메시지
         */
        public static String[] solution(String[] record) {
    
            int len = record.length;
    
            //유저 아이디, 닉네임 담을 map
            Map<String, String> map = new HashMap<>();
            //명령어, 유저 아이디 담을 list
            List<String[]> list = new ArrayList<>();
    
            for (int i = 0; i < len; i++) {
                StringTokenizer st = new StringTokenizer(record[i]);
                String cmd = st.nextToken();
                String user_id = st.nextToken();
    
                switch (cmd) {
                    case "Enter":
                        map.put(user_id, st.nextToken());
                        list.add(new String[]{cmd, user_id});
                        break;
                    case "Leave":
                        list.add(new String[]{cmd, user_id});
                        break;
                    case "Change":
                        map.replace(user_id, st.nextToken());
                        break;
                }
            }
    
            List<String> result = new ArrayList<>();
    
            for (String[] li : list) {
                String cmd = li[0];
                String user_id = li[1];
    
                if (cmd.equals("Enter")) {
                    result.add(map.get(user_id) + "님이 들어왔습니다.");
                } else {
                    result.add(map.get(user_id) + "님이 나갔습니다.");
                }
            }
            return result.toArray(new String[result.size()]);
        }
    }

    해시 2

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

    주의: 해시맵에 초기 세팅을 하지 않을 경우 NullPointerException이 발생한다.

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.stream.Stream;
    
    class Solution {
    
        /**
         * @param genres 고유번호가 i인 노래의 장르
         * @param plays 고유번호가 i인 노래가 재생된 횟수
         * @return 베스트 앨범에 들어갈 노래의 고유 번호 (각 장르별 2개씩. 1개일 경우 1개만 선택)
         */
        public static int[] solution(String[] genres, int[] plays) {
    
            Map<String, List<int[]>> genreMap = new HashMap<>(); //재생 횟수 별, 2차 정렬
            Map<String, Integer> playMap = new HashMap<>(); //장르 별, 1차 정렬
    
            for (int i = 0; i < genres.length; i++) {
                String genre = genres[i]; //장르
                int play = plays[i]; //재생 횟수
    
                //map에 장르가 없는 경우, 초기 세팅
                if (!genreMap.containsKey(genre)) {
                    genreMap.put(genre, new ArrayList<>());
                    playMap.put(genre, 0);
                }
                //값 세팅
                genreMap.get(genre).add(new int[]{i, play});
                playMap.put(genre, playMap.get(genre) + play);
            }
    
            //장르 별, 1차 정렬
            //총 재생 횟수가 많은 순으로 내림차순 정렬
            Stream<Map.Entry<String, Integer>> sortedByGenre = playMap.entrySet().stream()
                    .sorted(((o1, o2) -> Integer.compare(o2.getValue(), o1.getValue())));
    
            List<Integer> answer = new ArrayList<>();
    
            //재생 횟수 별, 2차 정렬
            //장르 내 재생 횟수가 많은 순으로 내림차순 정렬
            sortedByGenre.forEach(entry -> {
                //내림차순으로 정렬한 장르별로 genreMap 내부 순환
                Stream<int[]> sortedByPlay = genreMap.get(entry.getKey()).stream()
                        .sorted((o1, o2) -> Integer.compare(o2[1], o1[1])) //재생 횟수 내림차순 정렬
                        .limit(2); //최대 2개까지 제한
                //인덱스 값 반환
                sortedByPlay.forEach(song -> answer.add(song[0]));
            });
            return answer.stream().mapToInt(Integer::intValue).toArray();
        }
    }

    entrySet() vs keySet()

    • entrySet(): Map으로 정의된 모든 값을 가져와서 정의한다.
    • keySet(): Map으로 정의된 값 중에 key 값만 가져와서 정의한다.

    map의 모든 값을 가져와서 value 별로 내림차순 한다.

    Integer.compare(o2.getValue(), o1.getValue());

    Stream<Map.Entry<String, Integer>> sortedByGenre = playMap.entrySet().stream()
            .sorted(((o1, o2) -> Integer.compare(o2.getValue(), o1.getValue())));

    map의 key 값을 가져와서 value의 [1] 배열 별로 내림차순 한다.

    Integer.compare(o2[1], o1[1]);

    sortedByGenre.forEach(entry -> {
        //내림차순으로 정렬한 장르별로 genreMap 내부 순환
        Stream<int[]> sortedByPlay = genreMap.get(entry.getKey()).stream()
                .sorted((o1, o2) -> Integer.compare(o2[1], o1[1])) //재생 횟수 내림차순 정렬
                .limit(2); //최대 2개까지 제한
        //인덱스 값 반환
        sortedByPlay.forEach(song -> answer.add(song[0]));
    });
    728x90
    반응형

    'Blog > TIL' 카테고리의 다른 글

    [240613] java8 stream  (0) 2024.06.13
    [240612] swagger ui api 사용하기  (0) 2024.06.12
    [240610] 유스케이스 다이어그램을 작성해보다  (0) 2024.06.10
    [240609] 배울 게 태산  (0) 2024.06.09
    [240608] 환경설정 끄적끄적  (0) 2024.06.08

    댓글